shiro-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Les Hazlewood <lhazlew...@apache.org>
Subject Re: Subject-Session relationship
Date Wed, 11 Feb 2009 19:48:38 GMT
On Wed, Feb 11, 2009 at 11:51 AM, Razvan <razvan.software@gmail.com> 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.

Mime
View raw message