Hi Les, Thanks for the details, things are much clearer now.
P.S: My bad with the SecurityManager logout method. Best Regards, Razvan On Wed, Feb 11, 2009 at 7:48 PM, Les Hazlewood <[email protected]>wrote: > On Wed, Feb 11, 2009 at 11:51 AM, Razvan <[email protected]>wrote: > >> >> Hi Les, >> >> Thanks for your answer and the effort to write it in such details. > > > My pleasure! I did so because I think this thread can benefit many people > looking for similar capabilities, especially when it comes to dynamic > changes to the authorization model at runtime. > > > >> 2. Regarding the access to the active subjects, I personally do not find >> it >> as a performance problem from the following reasons : >> >> a) Subjects are already there, we would just need access to them ... For >> example, a SubjectStore and a SubjectListener or so, that updates the >> store >> on : login/logout etc. At the moment i have a similar solution implemented >> for my problem (store the subjects in Realm implementation) and am writing >> some test cases to see if it breaks somewhere. > > > This starts to go down JSecurity implementation details, and I didn't cover > this initially because most end-users should never really know about the > 'guts' of how Subjects function, and I didn't want to confuse the issue. > But, in case you're curious: > > With the SecurityManager default implementations, Subjects are not 'already > there'. It creates Subject instances that are extremely lightweight and > intended to be constructed and thrown away at the beginning and end of a > request/transaction respectively[1]. > > The Session however, is long lived - as it needs to be because of temporal > requirements. So, JSecurity's default Subject creation logic works as > follows: > > (Note this is _very_ implementation specific and developers should _not_ > code with these assumptions. They might change.) > > 1. Acquire a session ID based on the incoming request - either a method > invocation AOP proxy or Http Servlet Request or other means. > 2. Acquire the Session corresponding to the incoming ID > 3. From the Session, get the stored PrincipalCollection, authentication > state, and anything else needed to construct the Subject instance. > 4. Instantiate a Subject instance based on #3, which wraps the Session > acquired from #2 (so subject.getSession() returns the same Session). > 5. 'Bind' the Subject to the application. In most cases this means > binding the Subject to the currenctly executing Thread and/or > ServletRequest. > 6. Process the method invocation or servlet request > 7. Unbind the Subject instance from the executing thread and/or > ServletRequest. > > This might seem a little confusing since you might would assume that the > Subject instance itself 'lives' longer than the Session. But that's not the > case here. However, this is purely an implementation-specific technique and > can change - one day the Subject instance itself might persist somewhere > else - who knows. As of right now, it is very lightweight and can be > instantiated or garbage collected based on thread/request usage. > > >> >> >> b) You said it wouldn't be a good idea to allow access to this big number >> of >> objects but there is already access to all active sessions via >> DefaultSecurityManager -> DefaultSessionManager -> >> SessionDAO.getActiveSessions(). Is this path meant to be used in sessions' >> mgt/access ? Is it for JSecurity users or is it meant for JSecurity >> developers ? > > > It is meant for JSecurity developers only. The current implementation > pulls all Session instances in to memory as a default/simple technique to > ensure they are still valid. It isn't scalable for environments with > thousands of concurrent sessions, and exists only as a default fallback > mechanism - other implementations would do validation in some other way, > e.g. RDBMS query: "update sessions set stop_timestamp = ?, expired=true > where last_access_timestamp <= ?", where ? = 'now', i.e. new Date(); > > This might very well be faster than iterating over instances in memory if > there are many instances. Or not if 2nd level caching is being used. The > point is that it is an implementation-specific detail to be overridden in > these large-scale environments if necessary, strictly for session timestamp > validation. > > >> I will add a jira feature request because I think, first ... it might be >> useful in some conditions and may help avoiding workarounds and second ... >> it is a decent feature even if problems can be sorted in other ways as >> well. > > > You're more than welcome, but again, because of the implications in highly > concurrent environments (above), it might not be a good idea. If you see a > better approach to keeping things performant, we're all ears of course ;) > > 3. This is more a semantic question : >> >> Why method logout(Subject s) in DefaultSecurityManager behaves different >> from logout() in DelegatingSubject ? > > > There is no SecurityManager.logout(Subject) method call. There is a > SecurityManager.logout(PrincipalCollection) method though - the semantics > are different. End-users should rarely, if ever, interact with a > SecurityManager. The should however interact with > SecurityUtils.getSubject(), the Subject(), and the Session interfaces (and > any Annotations or JSP taglibs that exist). > > Cheers, > > Les > > [1] JSecurity 1.0 will have SubjectBinder and SubjectFactory interfaces to > abstract the details of how Subjects are bound and acquired even more > loosely coupled in case an application wants to control exactly how Subject > instances are made available to the application. However, developers for > any server-based application should think really hard before changing the > default request/transaction-based behavior. >
