I don't understand the cross-context issues, and I don't see how your proposal will result in us honoring null-false-null, especially given that we require a default subject to be set any time security settings are present (which I find a little weird; why not let it be null?). But other that that, your proposal sounds good to me. Thanks, Aaron On 8/10/06, David Jencks wrote: > 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 > >