You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by drmike01 <ms...@gmail.com> on 2012/08/18 00:04:52 UTC

Support for multiple session timeouts?

I'm trying to support an app that has multiple session timeouts depending on
how the users interact with it. One way is to use a mobile app, and the
other is a web-based version. Both access the same backend using AJAX, and I
use Shiro to authenticate those queries and handle the session timeouts.
Because the mobile app will only be used on locked mobile phones, I would
like to have the session timeout to be substantially longer than would be
acceptable for the web version (several hours v. ~15 minutes).

I understand that there should be only one SecurityManager per app, and
therefore only one SessionManager as well, and the timeouts are configured
in those, therefore only one session timeout. I've thought of two potential
ways of handling this given that I have to have one fixed session timeout,
but neither feels "right", and I'm wondering if I'm missing another option.

First option is to use my subclassed AuthenticatingFilter, use something
like subject.getSession().getLastAccessTime() as well as the path they're
accessing to figure out if it's too long for that particular path. If so,
use something like SimpleSession.setExpired(true) to kill the session. Not
sure if this will work, though, as the way the classes call each other is a
bit confusing to me.

The second would be to create a thread that routinely went through all the
active sessions, like the validator would, and do similar logic to step one
to expire the incorrect sessions. I'm worried this may be expensive,
particularly if I'm using a third party session management cache (like
Amazon's). I suppose I could also override the validation process, but that
seems a bit messy.

Thanks in advance for any suggestions.

Mike



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Support-for-multiple-session-timeouts-tp7577708.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Support for multiple session timeouts?

Posted by drmike01 <ms...@gmail.com>.
Hi Les,

Thanks for the info. This helped me to understand that setting the timeout
isn't an explicit "this will expire at this time" statement, but instead
setting the max idle duration that will be reset with every request (that
explains my incorrect getLastAccessTime() in my question).

Two questions related to your recommendations:

1) Could I not use the recommendation for servlet-based sessions with native
sessions as well? Although I'll have to dig around in the API to figure it
out, it seems like there would be a way to grab the Session from within a
Filter and change it. I'm thinking something like:
SecurityUtils.getSubject().getSession().setTimeout(x);
Possibly a lot of overhead with this approach because it would happen with
every request, but seems straightforward. For this reason alone, though, I
don't really want to do this.

2) For the SessionListener recommendation, I only partially understand the
comment re: using the ThreadLocal variable. I understand that it has to be
accessible from within the SessionListener, but you don't mean anything more
that that, correct? Based on what I can see, there isn't a way to get at
what the context path is for the http request from the listener, since
that's disconnected from the actual request itself. I was thinking I could
set a session attribute that I could access in this listener, but I think
that would require me touching the same method in SessionManager as the
other approach anyway because it would have to be there at the very
beginning to be available to the onStart() method.

Even if neither of the above work, though, you were kind enough to provide
we with nearly all the code for my subclassed DefaultWebSessionManager if I
need to go there, so thank you!

Mike 



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Support-for-multiple-session-timeouts-tp7577708p7577710.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Support for multiple session timeouts?

Posted by Les Hazlewood <lh...@apache.org>.
Hi Mike,

There are a couple of ways to do this:

If you're using the default servlet-container based sessions, you can
set up a servlet filter that calls
shiroSession.setTimeout(timeoutValue) during requests that match your
criteria.

If you are using Shiro's native session managers, you can implement a
SessionListener and listen for the onStart event and call
session.setTimeout there.  This would only work if the information you
need to set the timestamp can be obtained in the listener (e.g. using
a ThreadLocal to look at a thread-bound request).

Also, again if using Shiro's native session managers, if you need to
perform logic based on a request and you only want to set the timeout
when the session is created, you could subclass the SessionManager
implementation and override the start(SessionContext) method (start is
called whenever a new session needs to be created/started):

@Override
public Session start(SessionContext context) {
        Session session = createSession(context);

        applySessionTimeout(session, context);

        onStart(session, context);
        notifyStart(session);
        //Don't expose the EIS-tier Session object to the client-tier:
        return createExposedSession(session, context);
}

you'd create the applySessionTimeout method.  You can inspect the
context to see if it is a web context, and if so, inspect the request
to determine what session timeout to use, e.g.:

private void applySessionTimeout(Session session, SessionContext context) {
    if (WebUtils.isHttp(context)) {
        HttpServletRequest request = WebUtils.getHttpRequest(context);
        long timeout = getTimeout(request); //TODO: code getTimeout
        session.setTimeout(timeout);
    } else {
        super.applyGlobalSessionTimeout(session);
    }
}

This could be easier if we abstracted out a resolver, e.g.
sessionTimeoutResolver(Session session, SessionContext context), but
this is the first we've heard of such a need.  If you feel like  you'd
like to see this in Shiro, please open a Jira.  This may not be
necessary however if we set up a more robust event notification that
retains everything in the event (Session, SessionContext, etc), at
which point you can just implement an event listener and make the
change there since you'll have all necessary information.  I hope to
see this in 1.3.

If you can use the current SessionListener approach and pull the
request info off of a ThreadLocal, that would be the most
forward-compatible safe change IMO - mucking in the SessionManager
internals is a bit risky if you want to the easiest upgrade paths when
the next version of Shiro is released.  But at least it's there if you
don't have a ThreadLocal option!

I hope that helps!

Best,

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
Stormpath wins GigaOM Structure Launchpad Award! http://bit.ly/MvZkMk


On Fri, Aug 17, 2012 at 3:04 PM, drmike01 <ms...@gmail.com> wrote:
> I'm trying to support an app that has multiple session timeouts depending on
> how the users interact with it. One way is to use a mobile app, and the
> other is a web-based version. Both access the same backend using AJAX, and I
> use Shiro to authenticate those queries and handle the session timeouts.
> Because the mobile app will only be used on locked mobile phones, I would
> like to have the session timeout to be substantially longer than would be
> acceptable for the web version (several hours v. ~15 minutes).
>
> I understand that there should be only one SecurityManager per app, and
> therefore only one SessionManager as well, and the timeouts are configured
> in those, therefore only one session timeout. I've thought of two potential
> ways of handling this given that I have to have one fixed session timeout,
> but neither feels "right", and I'm wondering if I'm missing another option.
>
> First option is to use my subclassed AuthenticatingFilter, use something
> like subject.getSession().getLastAccessTime() as well as the path they're
> accessing to figure out if it's too long for that particular path. If so,
> use something like SimpleSession.setExpired(true) to kill the session. Not
> sure if this will work, though, as the way the classes call each other is a
> bit confusing to me.
>
> The second would be to create a thread that routinely went through all the
> active sessions, like the validator would, and do similar logic to step one
> to expire the incorrect sessions. I'm worried this may be expensive,
> particularly if I'm using a third party session management cache (like
> Amazon's). I suppose I could also override the validation process, but that
> seems a bit messy.
>
> Thanks in advance for any suggestions.
>
> Mike
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Support-for-multiple-session-timeouts-tp7577708.html
> Sent from the Shiro User mailing list archive at Nabble.com.