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/
