Les,

I couldn't see how I could disable the servlet container's default updating
of the lastAccessedTime. The way I understood it this was not being done by
Shiro but by Jetty (in my case). How would you suggest that I solve
something like this?

This is what I wanted to accomplish:

I want to provide a URL ("checkLogin") that can be called without the
lastAccessedTime being updated. The use case is to allow the web browser to
poll the server in order to check whether the session has been terminated.
If it has been terminated then a login dialog would automatically appear.
With the default behaviour, every call to the "checkLogin" URL would update
the lastAccessedTime and the session would never time out which would
defeat the purpose of calling the "checkLogin".

The way I interpreted the implementation of "updateSessionLastAccessTime"
was that it ensured that the lastAccessedTime would be updated even if
Shiro's native session were used instead of the web session. I want the
right opposite: I want to be able to prevent the lastAccessedTime to be
updated for certain URL's and I can't see how I can prevent the servlet
container from doing that.

How can I solve this by using Shiro's native sessions?

/Bengt


2011/11/11 Les Hazlewood <[email protected]>

> Hi Bengt,
>
> Why go through all of that - why not use Shiro's native session
> support (which I assume would give you the results you want)?
>
> Les
>
> P.S. the 'updateSessionLastAccessTime'  was added to support Shiro's
> native session needs in a web environment.  It ensures sessions behave
> correctly in a web environment (at least according to what the Servlet
> spec implies).
>
> On Fri, Nov 11, 2011 at 5:01 AM, Bengt Rodehav <[email protected]> wrote:
> > 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/
>

Reply via email to