geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <david_jen...@yahoo.com>
Subject Problems with security propagation between web apps and ejbs
Date Thu, 10 Aug 2006 21:47:42 GMT
A user noticed that when their web app called an ejb, despite the  
authentication of the user in the web app, in the ejb isCallerinRole  
always returns false.  I've been investigating this and think we have  
some problems in how we handle run-as identities and the  
ContextManager currentCaller and nextCaller values.  I'm also not  
sure where our defaultSubject idea fits into this.  I'll try to  
summarize my understanding of the specs and what we should be doing,  
and make a bit of a proposal.

I'd really appreciate some review of how I think its supposed to work  
and comments on my proposal.  I'm working on a patch to implement the  
proposal, but I believe we have to do something since what we do now  
appears to be broken.

web apps (2.4 spec):
SRV.12.3 states that the getRemoteUser, isUserInRole, and  
getUserPrincipal methods should return null, false, and null if there  
is no authenticated user.  Following the specs' usual policy of not  
discussing cross context dispatch, we are left to guess that even if  
a run-as role is specified somewhere the target of a cross-context  
dispatch should continue to return null, false, null with no actual  
authenticated user.

SRV.12.7 states that if a run-as element is specified, all calls from  
any servlet in the application to an ejb must be done under a subject  
associated with the run-as role.

The spec does not seem to account for the possiblity that calls to  
ejbs could be done either pre- or post- user authentication: if a run- 
as role is specified, all calls will be made using it whether or not  
the user is authenticated.

We've introduced the concept of a defaultSubject that is used if the  
user is not authenticated, but will not interfere with using the  
users actual identity when the user is authenticated.  IIUC (I  
haven't tested) currently the default subject is used in a way that  
interferes with the "null, false, null" requirements for  
getRemoteUser, isUserInrole, and getUserPrincipal.


ejbs: (2.1 spec)
21.3.4.1 indicates that the run-as identity specified for an ejb does  
not affect any security decisions for the ejb itself, but only  
specifies the identity to be used when it is calling other ejbs ( I  
need to check which identity is used use with resource adapters using  
container managed security).  Methods such as isCallerInRole use the  
caller's identity, not the run-as identity (21.2.5.1)

----------------

We're keeping track of these two identities in ContextManager  
currentCaller and nextCaller (threadLocals).  All security decisions  
are based on the currentCaller value.  When a run-as value is  
specified for an ejb, it's put into the nextCaller.  When an ejb is  
called, the nextCaller value is shifted into the currentCaller: this  
is supposed to occur before the run-as is put into the nextCaller.

My understanding of the requirements is that we should be:
- when a web user is authenticated we should put the subject into  
currentCaller and nextCaller.  The currentCaller value will be used  
for security decisions in the web app, and the nextCaller value for  
security decisions on any ejbs it calls.

- when a run-as role is specified for a web app we put the subject  
associated with the run-as role into nextCaller (whether or not the  
current user is authenticated)

- cross context dispatch may replace the nextCaller if run-as is  
specified for the target, and the previous nextCaller value needs to  
be restored on return.  This can never affect currentCaller.

- defaultSubject (a non-spec concept) should be put into both  
currentCaller and nextCaller unless run-as is specifed  in which case  
run-as goes in the nextCaller.

----------------

Currently the web security stuff is pretty much ignoring nextCaller  
which is causing the authenticated user to be lost in ejb calls: this  
causes the problem the user reported.  I'm mystified as to how the  
tck passes.

----------------

I think that perhaps we should organize this information into one  
object with more explicit operations on the ContextManager:

class Callers {
Subject currentCaller;
Subject nextCaller;
}

in ContextManager:

void setCallers(Subject currentCaller, Subject nextCaller)

//called for servlet cross context dispatch to set the target app run- 
as identity
Callers setNextCaller(Subject nextCaller);

//called for ejb call to shift the next caller to current caller and  
set the next caller to the run-as subject.
// We need either another method with no params for the "no run-as"  
case or if null is suppled the nextCaller is not changed
Callers pushNextCaller(Subject nextCaller);

//called on return from an ejb call or servlet-cross-context-dispatch.
void popCallers(Callers oldCallers);

This would reduce the number of thread locals in ContextManager by at  
least one.


Thanks
david jencks


Mime
View raw message