I've been trying to dig through the JBoss source to understand how the caller
principal is set for the home.create() call, and I think it's possible that
there is a bug in the JBoss code. It's definitely possiblet hat Im wrong and I
am just not understanding something correctly, but let me show you what I
looked at.
In org.jboss.ejb.plugins.SecurityInterceptor#setContainer, if the
runAsCallerIdentity() == true, which is default, the runAsIdentity is never
initialized and remains null.
| public void setContainer(Container container)
| {
| super.setContainer(container);
| if (container != null)
| {
| BeanMetaData beanMetaData = container.getBeanMetaData();
| ApplicationMetaData applicationMetaData =
beanMetaData.getApplicationMetaData();
| AssemblyDescriptorMetaData assemblyDescriptor =
applicationMetaData.getAssemblyDescriptor();
| securityRoles = assemblyDescriptor.getSecurityRoles();
|
| SecurityIdentityMetaData secMetaData =
beanMetaData.getSecurityIdentityMetaData();
| if (secMetaData != null && secMetaData.getUseCallerIdentity()
== false)
| {
| String roleName = secMetaData.getRunAsRoleName();
| String principalName = secMetaData.getRunAsPrincipalName();
|
| // the run-as principal might have extra roles mapped in
the assembly-descriptor
| Set extraRoleNames =
assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
| runAsIdentity = new RunAsIdentity(roleName, principalName,
extraRoleNames);
| }
|
| securityManager = container.getSecurityManager();
| realmMapping = container.getRealmMapping();
|
| try
| {
| // Get the timeout method
| ejbTimeout = TimedObject.class.getMethod("ejbTimeout", new
Class[]{Timer.class});
| }
| catch (NoSuchMethodException ignore)
| {
| }
| }
| }
Later on, in when an EJB looks up another EJB, the
org.jboss.ejb.plugins.SecurityInterceptor#invokeHome is called. There is a
call that indiscrimintately pushes the runAsIdentity onto the stack. Since
this is null from before, the next call is run with a null caller identity.
This is confirmed by the TRACE below.
| public Object invokeHome(Invocation mi) throws Exception
| {
| // Authenticate the subject and apply any declarative security checks
| checkSecurityAssociation(mi);
|
| /* If a run-as role was specified, push it so that any calls made
| by this bean will have the runAsRole available for declarative
| security checks.
| */
| SecurityActions.pushRunAsIdentity(runAsIdentity);
|
| try
| {
| Object returnValue = getNext().invokeHome(mi);
| return returnValue;
| }
| finally
| {
| SecurityActions.popRunAsIdentity();
| SecurityActions.popSubjectContext();
| }
| }
|
Here is the trace where you can see the caller identity of null being pushed,
and the subsequent exception that is caused by it.
| 2005-11-20 08:14:53,140 TRACE
[org.jboss.security.plugins.JaasSecurityManager.mwo] doesUserHaveRole(Set),
subject: Subject:
| Principal: admin
| Principal: Roles(members:Guest,Administrator)
|
| 2005-11-20 08:14:53,140 TRACE
[org.jboss.security.plugins.JaasSecurityManager.mwo]
roles=Roles(members:Guest,Administrator)
| 2005-11-20 08:14:53,140 TRACE
[org.jboss.security.plugins.JaasSecurityManager.mwo] hasRole(Administrator)=true
| 2005-11-20 08:14:53,140 TRACE
[org.jboss.security.plugins.JaasSecurityManager.mwo] hasRole=true
| 2005-11-20 08:14:53,140 TRACE [org.jboss.security.SecurityAssociation]
pushRunAsIdentity, runAs=null
| 2005-11-20 08:14:53,140 DEBUG [com.myejb.jboss.Session2SecurityProxy]
Entered setEJBContext(EJBContext)
| 2005-11-20 08:14:53,156 TRACE
[org.jboss.security.plugins.JaasSecurityManager.mwo] getPrincipal, cache info:
null
| 2005-11-20 08:14:53,156 TRACE [org.jboss.security.SecurityAssociation]
popRunAsIdentity, runAs=null
| 2005-11-20 08:14:53,156 TRACE [org.jboss.security.SecurityAssociation]
popSubjectContext, [EMAIL PROTECTED],subject=7683106}
| 2005-11-20 08:14:53,156 ERROR [org.jboss.ejb.plugins.LogInterceptor]
TransactionRolledbackException in method: public abstract
com.myejb.Session1Remote com.myejb.Session1Home.create() throws
javax.ejb.CreateException,java.rmi.RemoteException, causedBy:
| java.lang.IllegalStateException: No valid security context for the caller
identity
|
It seems the StatelessSessionInstanceInterceptor is responsible for pushing the
caller identity into the StatelessSessionEnterpriseContext, but it is pulling
it from the methodInvocation. I tried to trace this all the way back to where
the MethodInvocation was formed by looking at the proxy compiler, but I don't
think I understand it well enough. To me it didn't look like the principal is
set on the MI by the proxy itself, but I could be wrong.
When the code finally gets to the point where it calls getCallerPrincipal(),
here is the code that gets executed. I've watched this in the debugger. The
beanPrincipal is null, principal is null, and rm is not null, so it tries to
set the beanPrincipal by calling peekRunAsIdentity. As previously established,
this is null so I get the "No valid security context" error.
| Principal getCallerPrincipalInternal()
| {
| if (beanPrincipal == null)
| {
| RealmMapping rm = con.getRealmMapping();
| if (principal != null)
| {
| if (rm != null)
| beanPrincipal = rm.getPrincipal(principal);
| else
| beanPrincipal = principal;
| }
| else if (rm != null)
| {
| // Check for the caller's run-as identity, not this bean's
run-as
| beanPrincipal = SecurityActions.peekRunAsIdentity(1);
| if (beanPrincipal == null)
| {
| // Let the RealmMapping map the null principal
| beanPrincipal = rm.getPrincipal(principal);
| }
| }
| else
| { // Check for a unauthenticated principal value
| ApplicationMetaData appMetaData =
con.getBeanMetaData().getApplicationMetaData();
| String name = appMetaData.getUnauthenticatedPrincipal();
| if (name != null)
| beanPrincipal = new SimplePrincipal(name);
| }
| }
| if( beanPrincipal == null )
| {
| throw new IllegalStateException("No valid security context for
the caller identity");
| }
| return beanPrincipal;
| }
|
Is it possible that the invokeHome method in SecurityInterceptor should be
doing a conditional check on the pushRunAsIdentity? It seems that it should
not be pushing it if the intent is to run as the caller identity.
Thanks,
Matt
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3908070#3908070
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3908070
-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc. Get Certified Today
Register for a JBoss Training Course. Free Certification Exam
for All Training Attendees Through End of 2005. For more info visit:
http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click
_______________________________________________
JBoss-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jboss-user