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 <[email protected]> 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.

Reply via email to