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.
