You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Jim Newsham <jn...@referentia.com> on 2010/08/05 02:15:01 UTC

shiro session questions

Hi,

I'm looking at using shiro in a (swing-based) client/server application, 
using a "remoting" approach (like rmi, spring remoting, but this is a 
custom implementation as I won't be using shiro's spring support) -- so 
the client gets a remote proxy of some service interfaces that the 
server exports.

What I'm currently thinking is that authentication will be an explicit 
operation that the client can perform, which will result in it acquiring 
a session token that can be sent with each subsequent invocation 
request.  The server will use the session token provided by the client 
to add the appropriate subject to the invocation context before the 
invocation is made.  It looks like I can use shiro's session id as the 
session token.

1.  Can I create a session without logging in?  This might be useful if 
we implement some unprivileged client behavior which doesn't require login.

2.  If the user logs in and then subsequently logs out (or is timed 
out), is the session gone?  Is the session id no longer valid?  This 
would mean that I would have to send a new session id to the client.

3.  I understand that I can use the following to look up a subject for a 
given session:

subject = new 
Subject.Builder(securityManager).sessionId(sessionId).buildSubject();

But what happens if the sessionId is not valid?  Will I get a new 
(unauthenticated) subject without a session?  Will it implicitly create 
a session?  Will subject construction fail?  In my case, if the session 
is no longer valid I would need to construct a new session and then 
relay the new session id to the caller.

Thanks,
Jim

Re: shiro session questions

Posted by Jim Newsham <jn...@referentia.com>.
Hi Les,

Thanks for the detailed reply, that's exactly what I was looking for.  
Very helpful for me to understand how everything works, and definitely 
not "more than I was asking for". :)

Regards,
Jim

On 8/4/2010 2:54 PM, Les Hazlewood wrote:
> Hi Jim,  Please see inline:
>
>> I'm looking at using shiro in a (swing-based) client/server application,
>> using a "remoting" approach (like rmi, spring remoting, but this is a custom
>> implementation as I won't be using shiro's spring support) -- so the client
>> gets a remote proxy of some service interfaces that the server exports.
>>
>> What I'm currently thinking is that authentication will be an explicit
>> operation that the client can perform, which will result in it acquiring a
>> session token that can be sent with each subsequent invocation request.  The
>> server will use the session token provided by the client to add the
>> appropriate subject to the invocation context before the invocation is made.
>>   It looks like I can use shiro's session id as the session token.
> Yep, this is fairly common.  We have a Java Web Start sample
> application that you can use for ideas.  It uses Spring remoting, but
> the concepts are the same regardless of the remoting mechanism - you
> just need to ensure that the session ID accompanies the remoting
> payload somehow.
>
>> 1.  Can I create a session without logging in?  This might be useful if we
>> implement some unprivileged client behavior which doesn't require login.
> Yep, absolutely.  A subject.getSession() call will return a new
> session if one does not yet exist, regardless of
> authentication/rememberMe state.
>
>> 2.  If the user logs in and then subsequently logs out (or is timed out), is
>> the session gone?  Is the session id no longer valid?  This would mean that
>> I would have to send a new session id to the client.
> In the case of a log out or expiration timeout, any further
> interactions under the old session ID would cause an
> InvalidSessionException.  It is the responsibility of the client (or
> the server acting on behalf of the client) to catch these exceptions
> and act accordingly (e.g. transparently create a new session, or show
> the user some view to force a new login, etc).
>
> For example, Shiro's web support does this automatically (since the
> web layer is considered a client tier).  If the client browser sends
> an old session ID cookie, Shiro's web module will catch the exception
> and transparently remove the old session id cookie.  If the request
> then needs a new session, the new session's id is automatically added
> to the response as a new cookie.
>
> As to whether or not if the session is 'gone':  when a session is
> stopped explicitly, or stopped automatically via logout, or expired
> due to inactivity, in all cases that particular session is no longer
> usable.  However, the raw session data may still exist in the session
> backing data store (abstracted in Shiro via a SessionDAO).  The Shiro
> SessionManager implementation's default behavior is to permanently
> delete all sessions upon discovering they are stopped or expired.
> However, this behavior can be turned off where it is expected that
> some process external to Shiro will clean up the session store (e.g. a
> Quartz job or cron job) to prevent long-term orphans.  This feature
> exists because some people want to run queries on the data store to
> gather statistics about user's session usage (how long an average
> session lasts, how many sessions per user, etc).  (My personal feeling
> is that this doesn't scale well and that queries should be run on
> logged data sets, such as via Hadoop).
>
> This may be a little more than what you were asking for, but just know
> that in all cases, once a session has expired or is stopped, it can no
> longer be accessed by the application - at least not through Shiro.
>
> Finally, for rich client applications, the session.touch() method
> might be of interest.  It should be used appropriately to ensure that
> sessions aren't left open forever, but it could be useful in some
> situations.  That method's JavaDoc should help clarify things.
>
>> 3.  I understand that I can use the following to look up a subject for a
>> given session:
>>
>> subject = new
>> Subject.Builder(securityManager).sessionId(sessionId).buildSubject();
>>
>> But what happens if the sessionId is not valid?  Will I get a new
>> (unauthenticated) subject without a session?  Will it implicitly create a
>> session?  Will subject construction fail?  In my case, if the session is no
>> longer valid I would need to construct a new session and then relay the new
>> session id to the caller.
> The buildSubject() call in this case would fail with an
> InvalidSessionException - the assumption is that because you're
> providing a specific ID, you must know more than Shiro does that you
> expect a session to be there.
>
> However, it is quite easy to catch that exception and automatically
> build a new Subject if that occurs.   It is just hard for Shiro to do
> this automatically because it is very specific to the client being
> built, which is impossible for us to know about a priori.  But if
> anyone out there has suggestions to make this better, we're all ears!
>
> Anyway, I hope that helps!
>
> Best,
>
> Les


Re: shiro session questions

Posted by Les Hazlewood <lh...@apache.org>.
> Yep, this is fairly common.  We have a Java Web Start sample
> application that you can use for ideas.  It uses Spring remoting, but
> the concepts are the same regardless of the remoting mechanism - you
> just need to ensure that the session ID accompanies the remoting
> payload somehow.

I almost forgot - the addendum to this is that there is something on
the server side that intercepts the request, constructs the Subject
based on the sessionID, binds the subject to the thread, let's the
request or invocation continue, and then unbinds the subject from the
thread in a guaranteed manner.

We prefer that the subject.execute* methods are used to do the
automatic binding/unbinding.  In fact, Shiro's server-side
interception mechanisms do exactly this.  Take a look at the
SecureRemoteInvocationExecutor[1] 'invoke' method and the
AbstractShiroFilter[2] 'doFilterInternal' method implementations and
replicate that.

Cheers,

Les

[1] http://svn.apache.org/repos/asf/incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java
[2] http://svn.apache.org/repos/asf/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java

Re: shiro session questions

Posted by Les Hazlewood <lh...@apache.org>.
Hi Jim,  Please see inline:

> I'm looking at using shiro in a (swing-based) client/server application,
> using a "remoting" approach (like rmi, spring remoting, but this is a custom
> implementation as I won't be using shiro's spring support) -- so the client
> gets a remote proxy of some service interfaces that the server exports.
>
> What I'm currently thinking is that authentication will be an explicit
> operation that the client can perform, which will result in it acquiring a
> session token that can be sent with each subsequent invocation request.  The
> server will use the session token provided by the client to add the
> appropriate subject to the invocation context before the invocation is made.
>  It looks like I can use shiro's session id as the session token.

Yep, this is fairly common.  We have a Java Web Start sample
application that you can use for ideas.  It uses Spring remoting, but
the concepts are the same regardless of the remoting mechanism - you
just need to ensure that the session ID accompanies the remoting
payload somehow.

> 1.  Can I create a session without logging in?  This might be useful if we
> implement some unprivileged client behavior which doesn't require login.

Yep, absolutely.  A subject.getSession() call will return a new
session if one does not yet exist, regardless of
authentication/rememberMe state.

> 2.  If the user logs in and then subsequently logs out (or is timed out), is
> the session gone?  Is the session id no longer valid?  This would mean that
> I would have to send a new session id to the client.

In the case of a log out or expiration timeout, any further
interactions under the old session ID would cause an
InvalidSessionException.  It is the responsibility of the client (or
the server acting on behalf of the client) to catch these exceptions
and act accordingly (e.g. transparently create a new session, or show
the user some view to force a new login, etc).

For example, Shiro's web support does this automatically (since the
web layer is considered a client tier).  If the client browser sends
an old session ID cookie, Shiro's web module will catch the exception
and transparently remove the old session id cookie.  If the request
then needs a new session, the new session's id is automatically added
to the response as a new cookie.

As to whether or not if the session is 'gone':  when a session is
stopped explicitly, or stopped automatically via logout, or expired
due to inactivity, in all cases that particular session is no longer
usable.  However, the raw session data may still exist in the session
backing data store (abstracted in Shiro via a SessionDAO).  The Shiro
SessionManager implementation's default behavior is to permanently
delete all sessions upon discovering they are stopped or expired.
However, this behavior can be turned off where it is expected that
some process external to Shiro will clean up the session store (e.g. a
Quartz job or cron job) to prevent long-term orphans.  This feature
exists because some people want to run queries on the data store to
gather statistics about user's session usage (how long an average
session lasts, how many sessions per user, etc).  (My personal feeling
is that this doesn't scale well and that queries should be run on
logged data sets, such as via Hadoop).

This may be a little more than what you were asking for, but just know
that in all cases, once a session has expired or is stopped, it can no
longer be accessed by the application - at least not through Shiro.

Finally, for rich client applications, the session.touch() method
might be of interest.  It should be used appropriately to ensure that
sessions aren't left open forever, but it could be useful in some
situations.  That method's JavaDoc should help clarify things.

> 3.  I understand that I can use the following to look up a subject for a
> given session:
>
> subject = new
> Subject.Builder(securityManager).sessionId(sessionId).buildSubject();
>
> But what happens if the sessionId is not valid?  Will I get a new
> (unauthenticated) subject without a session?  Will it implicitly create a
> session?  Will subject construction fail?  In my case, if the session is no
> longer valid I would need to construct a new session and then relay the new
> session id to the caller.

The buildSubject() call in this case would fail with an
InvalidSessionException - the assumption is that because you're
providing a specific ID, you must know more than Shiro does that you
expect a session to be there.

However, it is quite easy to catch that exception and automatically
build a new Subject if that occurs.   It is just hard for Shiro to do
this automatically because it is very specific to the client being
built, which is impossible for us to know about a priori.  But if
anyone out there has suggestions to make this better, we're all ears!

Anyway, I hope that helps!

Best,

Les