Remote EJB (using remote-naming) with JAAS authentication (for secured ejb)
nephri Mar 1, 2017 2:28 AMHi,
I'm migrating a standalone java application that calls ejb on J2EE server for now calling EJBs on a WildFly 9.0.2 J2EE server (maybe Widfly 10 for customers using java 8+)
The java application calls EJBs and use JAAS for authentication.
On the server side, we use the SessionContext.getCallerPrincipal() for handle our in-app session mechanism.
At this time, the client side seems to be correctly authenticated (i have a JAAS Subject)
but on the ejb, when i call SessionContext.getCallerPrincipal() , i have always "anonymous"
I have to say that the ejb call succeed but without any caller identity information
The subject on the client side looks like
Objet :
Principal : 4628796b-723f-42b6-b14d-8a88444fed02
Principal : Roles(members)
Principal : CallerPrincipal(members:4628796b-723f-42b6-b14d-8a88444fed02)
Principal : username
I resume here relevant code that i use:
For the JNDI lookup, i use this code:
private static synchronized javax.naming.Context initClientContextJNDI() {
Properties props = new Properties();
try {
// java.naming.factory.initial
props.put( Context.INITIAL_CONTEXT_FACTORY , "org.jboss.naming.remote.client.InitialContextFactory" );
// java.naming.provider.url
props.put( Context.PROVIDER_URL , "http-remoting://localhost:8081" );
// java.naming.factory.url.pkgs
props.put( "jboss.naming.client.ejb.context" , true );
return new javax.naming.InitialContext(props);
}
catch(Exception e){ e.printStackTrace(); }
return null;
}
For the JAAS authentication, i use this code :
System.setProperty("java.security.auth.login.config", new File("xxxxxx\\wildfly9.config").getAbsolutePath() );
ApplicationCallbackHandler handler = new ApplicationCallbackHandler();
LoginContext loginContext = new LoginContext( "application" , handler );
loginContext.login();
Subject subject = loginContext.getSubject();
System.out.println("Authentification:" + subject );
The ApplicationCallbackHandler can fill credentials for callbacks NameCallback and PasswordCallback
The wildfly9.config giving the JAAS login context configuration is like;
application {
// Login Module to use custom authentication
mycie.util.jaas.PasswordLoginModule required;
// Login Module to use for WILDFLY Authentication
org.jboss.security.ClientLoginModule required;
};
The PasswordLoginModule extends AbstractServerLoginModule and set
- a SimplePrincipal with a unique session id
- a SimpleGroup named "Roles" (found this from some documentation)
On the server side, my EJB is configured as follow:
@Stateless
@Local(TestLocal.class)
@Remote(Test.class)
@PermitAll
@SecurityDomain(value="mycie")
public class TestBean implements Test , TestLocal {
private static final double TX = 6.55957d;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public double euroToFranc(double euro) {
System.out.println("caller: " + getSessionContext().getCallerPrincipal() );
return euro * TX;
}
}
I set the @PermitAll for enable SecurityInterceptor (i readed that from EJB 3.1 specs)
But from some jboss/wildfly documentations, i readed that we should set the @SecurityDomain (i tried with or without it)
That where my knowledge in wildfly limit me. i'm thinking i may have configuration issues related to the security-domain
I created a security-realm like this:
<security-realm name="MyCieRealm">
<authentication>
<jaas name="MyCie"/>
</authentication>
</security-realm>
In the subsystem urn:jboss:domain:ejb3:3.0 , the http-remoting-connector didn't specify any security-realm
- if i set one, it's shared by the remote-naming when i perform JNDI. But i didn't want credentials for the JNDI lookup.
In the subsystem urn:jboss:domain:security:1.2, i created a security-domain:
<security-domain name="MyCie" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="mycie.util.jaas.CustomLoginModule" flag="required" module="mycie_domain"/>
</authentication>
</security-domain>
This security-domain is a random try from some code snipped found on the web but i didn't understand what i should do here !!!
(i created a module mycie_domain with small jar and a small CustomLoginModule accepting the authentication, but it doesn't seems to be used because i set a breakpoint and never be suspended on these code)
I'm a newbie in WildFly, i tried to be the most complete as possible for giving you efficients informations.
If you need some other kind of informations, don't hesitate.
Any help are welcome
Best regards,
Sébastien.