Remote call to secure EJB fails
pdesai Mar 2, 2006 5:08 PMI am trying to call secure EJB from outside the JVM using a simple java client.
Here are the steps I followed to configure my client -
1. Defined auth.conf file
client-login{ org.jboss.security.ClientLoginModule required; };
2. Wrote the client that make a call to secure EJB -
try{ String password = "admin"; AppCallbackHandler handler = new AppCallbackHandler( "admin", password.toString().toCharArray()); lc = new LoginContext("client-login", handler); System.out.println("Created LoginContext"); lc.login(); } catch (LoginException le){ System.out.println("Login failed" + le.toString()); } InitialContext initialContext = new InitialContext(props); Object objRef = initialContext.lookup("SecureOperations"); SecureOperationsHome sohome = (SecureOperationsHome)PortableRemoteObject.narrow(objRef,SecureOperationsHome.class); SecureOperations sosb = sohome.create(); //Calling secure operation on EJB sosb.testSecurity();
Here is the AppCallbackHandler
public static class AppCallbackHandler implements CallbackHandler{ private String username; private char[] password; public AppCallbackHandler(String username, char[] password){ this.username = username; this.password = password; } public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException{ for (int i = 0; i < callbacks.length; i++){ if (callbacks instanceof NameCallback){ NameCallback nc = (NameCallback)callbacks; nc.setName(username); } else if (callbacks instanceof PasswordCallback){ PasswordCallback pc = (PasswordCallback)callbacks; pc.setPassword(password); }else{ throw new UnsupportedCallbackException(callbacks, "Unrecognized Callback"); } } } }
3. When running the client, I am using -Djava.security.auth.login.config=auth.conf
On the JBoss server, here are the configuration steps I followed
1. Configure authentication policy in login-config.xml
<application-policy name = "jmx-console"> <authentication> <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required"> <module-option name = "dsJndiName">java:/OracleTxDS</module-option> <module-option name = "principalsQuery">SELECT PASSWORD FROM USERS WHERE NAME=?</module-option> <module-option name = "rolesQuery">SELECT USERROLES, 'Roles' FROM USERROLES WHERE USERNAME=?</module-option> <login-module code = "org.jboss.security.ClientLoginModule" flag = "required"> </login-module> </login-module> </authentication> </application-policy>
2. Defined the security domain in jboss.xml
<security-domain>java:/jaas/jmx-console</security-domain>
3. Defined security for the EJB in ejb-jar.xml
<ejb-name>SecureOperations</ejb-name> <home>com.test.ejb.interfaces.SecureOperationsHome</home> <remote>com.test.ejb.interfaces.SecureOperations</remote> <ejb-class>com.test.ejb.SecureOperationsSession</ejb-class> <session-type>Stateless</session-type> <transaction-type>Bean</transaction-type> <security-role-ref> <role-name>JBossAdmin</role-name> <role-link>JBossAdmin</role-link> </security-role-ref> <security-role> <description>The role required to invoke the SecureOperations method</description> <role-name>JBossAdmin</role-name> </security-role> <!-- The methods the JBossAdmin role can access --> <method-permission> <role-name>JBossAdmin</role-name> <method> <ejb-name>SecureOperations</ejb-name> <method-name>*</method-name> </method> </method-permission>
The client throws an exception when it tries to create an remote interface. Seems like the username and password information is
not getting propogated to the server. Am I missing anything?
Note: I used the same authentication policy to secure jmx-console and I was able to authenticate successfully
Here is the log file on the server
2006/03/02 17:07:36.545 TRACE XMLLoginConfigImpl.getAppConfigurationEntry() : End getAppConfigurationEntry(jmx-console), authInfo=AppConfigurationEntry[]:
[0]
LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule
ControlFlag: LoginModuleControlFlag: required
Options:name=rolesQuery, value=SELECT USERROLES, 'Roles' FROM USERROLES WHERE USERNAME=?
name=principalsQuery, value=SELECT PASSWORD FROM USERS WHERE NAME=?
name=dsJndiName, value=java:/OracleTxDS
[1]
LoginModule Class: org.jboss.security.ClientLoginModule
ControlFlag: LoginModuleControlFlag: required
Options:
2006/03/02 17:07:36.551 TRACE AbstractServerLoginModule.initialize() : initialize
2006/03/02 17:07:36.558 TRACE DatabaseServerLoginModule.initialize() : DatabaseServerLoginModule, dsJndiName=java:/OracleTxDS
2006/03/02 17:07:36.565 TRACE DatabaseServerLoginModule.initialize() : principalsQuery=SELECT PASSWORD FROM USERS WHERE NAME=?
2006/03/02 17:07:36.571 TRACE DatabaseServerLoginModule.initialize() : rolesQuery=SELECT USERROLES, 'Roles' FROM USERROLES WHERE USERNAME=?
2006/03/02 17:07:38.286 TRACE AbstractServerLoginModule.login() : login
2006/03/02 17:07:38.292 TRACE UsernamePasswordLoginModule.login() : Authenticating as unauthenticatedIdentity=null
2006/03/02 17:07:40.809 TRACE AbstractServerLoginModule.abort() : abort
2006/03/02 17:07:40.816 TRACE JaasSecurityManager.authenticate() : Login failure
javax.security.auth.login.FailedLoginException: No matching username found in Principals
at org.jboss.security.auth.spi.DatabaseServerLoginModule.getUsersPassword(DatabaseServerLoginModule.java:103)
at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:156)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:675)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:129)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:607)
at javax.security.auth.login.LoginContext.login(LoginContext.java:534)
at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:480)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:420)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:237)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:210)
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:151)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:74)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
at org.jboss.ejb.StatelessSessionContainer.internalInvokeHome(StatelessSessionContainer.java:319)
at org.jboss.ejb.Container.invoke(Container.java:729)
at sun.reflect.GeneratedMethodAccessor94.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.mx.server.ReflectedDispatcher.dispatch(ReflectedDispatcher.java:60)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:62)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:54)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:82)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:198)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:473)
at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:360)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)