Remote EJB invocation SWING client vs JBoss 7.1.3 wrong credentials
skazy Mar 15, 2013 6:15 AMI was assigned a task to migrate application from JBoss 4.2.2GA to JBoss AS 7.1.3. Everything went fine, but now I'm stuck with remote EJB invocation from SWING client.
In the documentation ([https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project]) I realized that JBoss AS 7.x doesn't have the implementation of JNP (for lookup the EJB beans via JNDI tree) any more. It was available on JBoss version 4.x, 5.x and 6.x which we use for EJB invocation of secured EJB beans with annotation @SecurityDomain.
On JBoss AS7 the alternative of JNP standard is EJB Client API where I have encountered the problem that on the SWING client's SessionContext is registered the Caller Principal with wrong Principals (username). I will describe detail scenario a bit later.
On JBoss Community forum I found the post [https://community.jboss.org/thread/196943] which describes the same problem as I have. We have remote EJB invocations of some EJB beans that are unsecured and the other that are secured by @SecurityDomain annotation. Remote invocation of unsecured EJB beans is not possible any more because the remoting-connector for remote EJB invocation have to be secured by default. More information on this in on [https://community.jboss.org/wiki/AS710Beta1-SecurityEnabledByDefault].
On the other post [https://community.jboss.org/thread/176963] I found the "Correct answer" with provided link [https://community.jboss.org/thread/195501?start=0&tstart=0]. It's a post where Darran and Anil describes details about Remoting. Unfortunately, I can't open it because my forum account is not authorized.
Does anyone know the detail compact instructions about JBoss configuriations and usage of EJB Client API and remoting?
Here is a detailed description about my problem and settings on JBoss server (standalone.xml), SWING client and finally the use case of Remote EJB invocation. It was done by collecting pieces of information from JBoss Community forum and JBoss AS 7 poor documentation.
1. The settings in $JBOSS_HOME$/standalone/configuration/standalone.xml:
...
<!-- Application realm for authentication of remoting-connector. -->
<security-realms>
…
<security-realm name="ApplicationRealm">
<authentication>
<local default-user="$local" allowed-users="*"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
</security-realms>
…
<!-- Remoting connector has the security realm named ApplicationReal where I defined the user root by add-user.bat. -->
<subsystem xmlns="urn:jboss:domain:remoting:1.1">
<connector name="remoting-connector" socket-binding="remoting" security-realm=" ApplicationRealm "/>
</subsystem>
…
<!--
Here two security domains are defined. First (other) is used for authentication of remoting connector,
second (app-security) is used to secure EJB beans by @SecurityDomain.
-->
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmUsersRoles" flag="required">
<module-option name="usersProperties" value="${jboss.server.config.dir}/application-users.properties"/>
<module-option name="rolesProperties" value="${jboss.server.config.dir}/application-roles.properties"/>
<module-option name="realm" value="ApplicationRealm"/>
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>
…
<security-domain name="app-security" cache-type="default">
<authentication>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="unauthenticatedIdentity" value="guest"/>
<module-option name="dsJndiName" value="java:/APP-DS"/>
<module-option name="principalsQuery" value="select password from user where username = ?"/>
<module-option name="rolesQuery" value="select name, 'Roles' from roles where username = ?"/>
</login-module>
</authentication>
</security-domain>
</security-domains>
</subsystem>
2. javax.naming.InitialContext
On SWING client's classpath I add jboss-ejb-client.properties which is used for remote connection (InitialContext) of client to server.
Remoting Connector uses credentials of user root from security realm ApplicationRealm.
Details of file are below:
endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=true
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
remote.connection.default.username=root
remote.connection.default.password=password
The InitialContext was created by jndi parameters:
Hashtable<String, Object> jndiProperties = new Hashtable<String, Object>();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put("jboss.naming.client.ejb.context", true);
context = new InitialContext(jndiProperties);
3. JNDI name:
application = app.ear
EJB jar = business_ejb.jar
bean name = APPBeanEJB
remote interface = APPBean
ejb:app/business_ejb//APPBeanEJB!com.business.APPBean
4. Login on SWING client:
SWING Client use org.jboss.security.ClientLoginModule for authentication of client's user "admin"
java.net.URL authUrl = AdminSystemTools.class.getClassLoader().getResource("auth.conf");
System.setProperty("java.security.auth.login.config", authUrl.toString());
AppCallbackHandler handler = new AppCallbackHandler(username, password.toCharArray());
LoginContext loginContext = new LoginContext("client-login", handler);
loginContext.login();
Content of auth.conf:
client-login{org.jboss.security.ClientLoginModule required;};
Now it's time for UseCase where I encountered the problem of wrong principal on SWING client context:
1. we have two EJB stateless beans beanA and beanB. The first one is unsecured bean and second one is secured by security domain @SecurityDomain("app-security")
2. user of SWING Client application has the username "admin" which principals belongs to security domain app-security,
3. when user admin starts SWING client, unsecured beanA is called. Remoting Connector is secured so first authentication (ApplicationRealm) is performed by user root,
4. the remote-connector passed the authentication successfully. Now the secured EJB beanB (security domain app-security) is called. Because the authentication of "app-security" wasn't done yet, user admin gets login dialog. Admin enters username "admin" and password and starts login process and SWING application is started succesfully. But SWING client application has wrong principals on SessionContext. It has root's principal instead of admin's principal.
It seems that org.jboss.security.ClientLoginModule transfers admin's principal to Security system unsuccessfuly.
Does anybody knows what the problem is?