Tomcat Standalone / JAAS / JBoss EJB Container
n_gyamlani Feb 15, 2006 1:45 PMHi,
I have been struggling with JAAS based Authentication since a couple of days in order to make it work with the following architecture
Standalone Tomcat : To be used to protected web resources using the JAASRealm configured with the DatasourceLoginModule and ClientLoginModule
JBoss Application Server : The EJBs are secure and need to be executed only by authorized users.
I have gone through almost all the relevant posting but am still having the famous "principal=null" issue on the EJB layer. So I wrote a standalone client which seems to be working seamlessly. I also tried the same setup using a LoginAction which executes the login() method of the LoginContext object explicitly, and this seems to be working fine too. I could use this approach, but then I would have to verify each incoming request (on the web-container) for authentication status.
As a basis for the tests I used the jaashow 3.2 examples after splitting it up for the web and application layers.
The error that is thrown after executing the login on the web-layer (while calling the echo() method on the public session is :
Tomcat Console output :
****************************************************
java.rmi.AccessException: SecurityException; nested exception is:
java.lang.SecurityException: Insufficient method permissions, principal=null, ejbName=PublicSession, method=echo
, interface=REMOTE, requiredRoles=[Echo], principalRoles=[] ..
****************************************************
However, the request.getUserPrincipal returns : GenericPrincipal[java(Echo,)] and I am permitted to use the "restricted"
resources available only to users with the "Echo" role-name.
My configuration is as follows :
Tomcat Standalone server.xml
****************************************************
Realm className="org.apache.catalina.realm.JAASRealm"
appName="jaasClientRealm"
****************************************************
Tomcat Standalone startup.bat
****************************************************
-Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaasLogin.config
****************************************************
The jaasLogin.conf (JaasClientRealm) section configured for the following :
DatasourceLoginModule (working with a hsqldb datasource)
ClientLoginModule(???????????)
DummyLoginModule (A simple module that served as a marker whether the configuration was functioning .. simply throws out System.out.println() on execution)
****************************************************
jaasClientRealm{
org.jboss.security.auth.spi.DatabaseServerLoginModule required
dsJndiName="java:comp/env/jdbc/HsqldbDS"
principalsQuery="select PASSWORD from PRINCIPALS where PRINCIPALID=?"
rolesQuery="select ROLE, ROLEGROUP from ROLES where PRINCIPALID=?"
unauthenticatedIdentity=nobody
;
org.jboss.security.ClientLoginModule required multi-threaded="false" restore-login-identity="false" password-stacking="useFirstPass"
;
de.msg.security.jaas.modules.DummyLoginModule required
;
};
****************************************************
As I mentioned earlier, the execution of the EJB methods functions flawlessly from a standalone client or if I use a LoginAction to explicitly call the login method.
I first thought it might have something to do with the multi-threaded parameter of the ClientLoginModule but setting it to "true" didn't help either.
Enabling the logging for org.jboss.security on the server side throws the following :
****************************************************
LoginModule Class: org.jboss.security.auth.spi.UsersRolesLoginModule
ControlFlag: Anmeldemodul-Steuerflag: required
Options:
19:28:54,333 TRACE [UsersRolesLoginModule] initialize, instance=@9939622
19:28:54,343 TRACE [UsersRolesLoginModule] findResource: null
19:28:54,353 TRACE [UsersRolesLoginModule] Properties file=jar:file:/D:/projekte/APKV/AppS/jboss-4.0.3SP1/server/jaas_ho
wto/tmp/deploy/tmp58598tutorial1.ear-contents/ssbean1.jar!/users.properties, defaults=null
19:28:54,363 DEBUG [UsersRolesLoginModule] Loaded properties, users=[ngyamlani, duke, java]
19:28:54,363 TRACE [UsersRolesLoginModule] findResource: null
19:28:54,373 TRACE [UsersRolesLoginModule] Properties file=jar:file:/D:/projekte/APKV/AppS/jboss-4.0.3SP1/server/jaas_ho
wto/tmp/deploy/tmp58598tutorial1.ear-contents/ssbean1.jar!/roles.properties, defaults=null
19:28:54,373 DEBUG [UsersRolesLoginModule] Loaded properties, users=[n_gyamlani, n_gyamlani.CallerPrincipal, duke, java,
java.CallerPrincipal, duke.CallerPrincipal]
19:28:54,373 TRACE [UsersRolesLoginModule] login
19:28:54,373 TRACE [UsersRolesLoginModule] Authenticating as unauthenticatedIdentity=null
19:28:54,373 DEBUG [UsersRolesLoginModule] Bad password for username=null
19:28:54,373 TRACE [UsersRolesLoginModule] abort
19:28:54,393 TRACE [example1] Login failure
javax.security.auth.login.FailedLoginException: Password Incorrect/Password Required
at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:189)
at org.jboss.security.auth.spi.UsersRolesLoginModule.login(UsersRolesLoginModule.java:137)
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:572)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:506)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:315)
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:196)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:120)
at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:121)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
at org.jboss.ejb.SessionContainer.internalInvokeHome(SessionContainer.java:613)
at org.jboss.ejb.Container.invoke(Container.java:894)
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 org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:245)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
at org.jboss.invocation.jrmp.server.JRMPInvoker$MBeanServerAction.invoke(JRMPInvoker.java:805)
at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:406)
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)
************************************************************
And the output when I use the standalone client to access the ejb with username = java and password = echoman
************************************************************
19:35:43,711 TRACE [example1] roles=Roles(members:Echo)
19:35:43,711 TRACE [example1] hasRole(Echo)=true
19:35:43,711 TRACE [example1] hasRole=true
19:35:43,711 INFO [STDOUT] PublicSessionBean.echo, isCallerInRole('EchoUser')=true
19:35:43,731 TRACE [SecurityAssociation] getPrincipal, principal=java
19:35:43,751 TRACE [SecurityAssociation] dupSubjectContext, sc=org.jboss.security.SecurityAssociation$SubjectContext@ccc
621{principal=java,subject=31702966}
19:35:43,751 TRACE [SecurityAssociation] pushRunAsIdentity, runAs=null
19:35:43,751 DEBUG [StatefulSessionContainer] Created new session ID: ejpzk64n-4
19:35:43,751 DEBUG [StatefulSessionContainer] Using create method for session: public void org.jboss.docs.jaas.howto.Pri
vateSessionBean.ejbCreate() throws javax.ejb.CreateException
19:35:43,751 INFO [STDOUT] PrivateSessionBean.ejbCreate() called
19:35:43,751 DEBUG [ProxyFactory] seting invoker proxy binding for stateful session: stateful-rmi-invoker
19:35:43,751 TRACE [SecurityAssociation] popRunAsIdentity, runAs=null
19:35:43,751 TRACE [SecurityAssociation] popSubjectContext, sc=org.jboss.security.SecurityAssociation$SubjectContext@ccc
621{principal=java,subject=31702966}
19:35:43,751 INFO [STDOUT] PublicSessionBean.echo, created PrivateSession
19:35:43,761 TRACE [SecurityAssociation] getPrincipal, principal=java
19:35:43,761 TRACE [SecurityAssociation] pushSubjectContext, subject=null, sc=org.jboss.security.SecurityAssociation$Sub
jectContext@396fce{principal=java,subject=null}
19:35:43,772 TRACE [SecurityAssociation] dupSubjectContext, sc=org.jboss.security.SecurityAssociation$SubjectContext@396
fce{principal=java,subject=null}
19:35:43,772 TRACE [SecurityAssociation] pushRunAsIdentity, runAs=null
19:35:43,772 INFO [STDOUT] PrivateSessionBean.echo, arg=Hello Motto
19:35:43,772 TRACE [example1] getPrincipal, cache info: org.jboss.security.plugins.JaasSecurityManager$DomainInfo@11af7b
b[Subject(14227847).principals=org.jboss.security.SimplePrincipal@26753751(java)org.jboss.security.SimpleGroup@3699202(R
oles(members:Echo))org.jboss.security.SimpleGroup@3699202(CallerPrincipal(members:caller_java)),credential.class=[C@1653
1630,expirationTime=1140030320077]
19:35:43,772 INFO [STDOUT] PrivateSessionBean.echo, callerPrincipal=caller_java
19:35:43,772 INFO [STDOUT] PrivateSessionBean.echo, isCallerInRole('InternalUser')=true
19:35:43,772 TRACE [SecurityAssociation] popRunAsIdentity, runAs=null
19:35:43,772 TRACE [SecurityAssociation] popSubjectContext, sc=org.jboss.security.SecurityAssociation$SubjectContext@396
fce{principal=java,subject=null}
19:35:43,772 TRACE [SecurityAssociation] popSubjectContext, sc=org.jboss.security.SecurityAssociation$SubjectContext@396
fce{principal=java,subject=null}
19:35:43,772 TRACE [SecurityAssociation] popRunAsIdentity, runAs=[roles=[InternalUser],principal=anonymous]
19:35:43,772 TRACE [SecurityAssociation] popSubjectContext, sc=org.jboss.security.SecurityAssociation$SubjectContext@ccc
621{principal=java,subject=31702966}
19:37:03,716 DEBUG [LRUEnterpriseContextCachePolicy] Running RemoverTask
19:37:03,716 DEBUG [LRUEnterpriseContextCachePolicy] RemoverTask, PassivatedCount=0
19:37:03,716 DEBUG [AbstractInstanceCache] removePassivated, now=1140028623716, maxLifeAfterPassivation=1200000
19:37:03,716 DEBUG [LRUEnterpriseContextCachePolicy] RemoverTask, done
*****************************************************
Would really really appreciate any help or guidance concerning the above.
Thanks in advance
Nikhil