Manoj,
This is what I ended up doing:
The session timeout is handled by the underlying servlet container (Jetty
in my case) not by Shiro. The code you pointed me to is only used when
Shiro takes care of the session handling (not in a servlet context).
Unfortunately there is no way to set the lastAccessedTime in a servlet
container. The API only includes a getter. Therefore, I don't see any way
of stopping Jetty from updating the lastAccessedTime. I therefore disable
the standard session timeout (by setting it to -1). I then implement my own
session timeout.
I created my own subclass from IniShiroFilter and made an override of the
method "updateSessionLastAccessTime". I create my own session attribute for
storing the lastUsed time. In my "updateSessionLastAccessTime" I update
that attribute unless the request path is my special path ("checkLogin"
that should be called without updating lastUsed).
In that method I also check if the session should expire (I have a
configurable timeout for this). Unless the request path was either of
"login" or "logout", I end the session if the timeout has expired.
This solution seems to work fine although I think I've had to "roll my own"
a bit too much. Perhaps functionality like this could make it into Shiro? I
think the usecase should be useful for others as well.
/Bengt
2011/11/10 Bengt Rodehav <[email protected]>
> OK - thanks Manoj,
>
> I'll take a deeper look in the code.
>
> /Bengt
>
>
> 2011/11/9 Manoj Khangaonkar <[email protected]>
>
>> Hi Bengt,
>>
>> The doFilterInternal method of AbstractShiroFilter starts the chain of
>> code that
>> extracts the sessionid from the request, locates the session, creates
>> the WebDelegatingSubject
>> whose session is touched.
>>
>> To get the behaviour you need, you might need to override some of this
>> code
>>
>> Manoj
>>
>> On Wed, Nov 9, 2011 at 12:50 AM, Bengt Rodehav <[email protected]> wrote:
>> > Hello Manoj,
>> > I use my own subclass of FormAuthenticationFilter. I've changed the
>> > behaviour of onAccessDenied() so that a 401 is returned since I do not
>> want
>> > a redirect to a login URL. It's an Ajax application so I don't want a
>> page
>> > reload. This seems to work.
>> > My first idea was to just have a special GET Url
>> (.../session/checkLogin)
>> > that the client would call. I assume that the web browser will send the
>> > session cookie (like it always does). On the server side I'm not clear
>> of
>> > what exactly happens. However, since there is a last used property on
>> the
>> > sesssion and I have set the session timeout, I assumed that all calls
>> within
>> > a session (determined from the session cookie) would "automagically"
>> update
>> > the last used timestamp. Not sure if this is Shiro functionality or
>> general
>> > Jetty functionality (Jetty is used for the OSGi http service that I'm
>> > using).
>> > It's not clear to me how I can tell (Shiro or Jetty?) that this
>> particular
>> > call should not "count". You're saying that subject.isAuthenticated()
>> does
>> > not touch the session but I would guess that
>> > calling SecurityUtils.getSubject() to get the subject needs the session
>> to
>> > work.
>> > When exactly is the last used property updated?
>> > BTW, I have a "login" method (POST .../session/login) that looks
>> something
>> > like this:
>> > String username = theRequest.getParameter("j_username");
>> > String password = theRequest.getParameter("j_password");
>> > LoginStatus status = getStatus();
>> > if (!getStatus().isAuthenticated()) {
>> > UsernamePasswordToken token = new UsernamePasswordToken(username,
>> > password);
>> > Subject currentUser = SecurityUtils.getSubject();
>> > try {
>> > currentUser.login(token);
>> > status = new LoginStatus(currentUser.isAuthenticated(),
>> > currentUser.getPrincipal().toString(), currentUser
>> > .getPrincipal().toString());
>> > HttpSession session = theRequest.getSession();
>> > if (session != null) {
>> > session.setMaxInactiveInterval(mService.getSessionTimeout());
>> > }
>> > } catch (AuthenticationException e) {
>> > status = new LoginStatus(false, null, null);
>> > }
>> > }
>> > Thus I set the session timeout on the HttpSession after a successful
>> login.
>> > /Bengt
>> >
>> > 2011/11/8 Manoj Khangaonkar <[email protected]>
>> >>
>> >> Hi Bengt,
>> >>
>> >> How do you plan on doing checkLogin ?
>> >>
>> >> If you use subject.isAuthenticated() , it does not touch the session.
>> >>
>> >> If you use an authenticationFilter like the FormAuthenticationFilter,
>> >> it can detect that the session has timed out
>> >> and redirect the request to a login url
>> >>
>> >> Manoj
>> >>
>> >>
>> >> On Tue, Nov 8, 2011 at 11:59 AM, Bengt Rodehav <[email protected]>
>> wrote:
>> >> > Seems like I've been bombarding this list lately. I'm quite new to
>> Shiro
>> >> > which is why I ask all these silly questions. Must say that I'm very
>> >> > pleased
>> >> > so far. Shiro has turned out to be much easier to use then Spring
>> Acegi
>> >> > that
>> >> > I have been using in the past.
>> >> > Anyway, I'm using Shiro 1.1 to handle authentication for an OSGi
>> based
>> >> > web
>> >> > application using the http service in Apache Karaf.
>> >> > Currently my web application will return status 401 when trying to
>> >> > access
>> >> > resources that requires an authenticated user in case the session
>> does
>> >> > not
>> >> > contain an authenticated user. I would like to enhance the web
>> >> > application
>> >> > so that the client (the browser) can periodically (e g once a minut)
>> can
>> >> > check whether a user is still logged in. That way, if a user leaves
>> the
>> >> > application for a while, I can display a login dialog so that the
>> user
>> >> > can
>> >> > clearly see that s/he has been logged out.
>> >> > The problem is that if the client calls my "checkLogin" method in the
>> >> > context of the current session once a minute then the session will
>> never
>> >> > time out since the last used timestamp will be updated on each call.
>> Is
>> >> > there a best practice to accomplish this? I'm not sure if it's
>> possible
>> >> > to
>> >> > make a call "outside" of the session. I was thinking about saving the
>> >> > last
>> >> > used timestamp in another session attribute and then restore the real
>> >> > last
>> >> > used timestamp from my special attribute after invoking my
>> "checkLogin"
>> >> > method. Not sure if that would work and thought it might be wise to
>> ask
>> >> > if
>> >> > anyone has done something similar before.
>> >> > /Bengt
>> >>
>> >>
>> >>
>> >> --
>> >> http://khangaonkar.blogspot.com/
>> >
>> >
>>
>>
>>
>> --
>> http://khangaonkar.blogspot.com/
>>
>
>