shiro-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bengt Rodehav <be...@rodehav.com>
Subject Re: Check if a user is authenticated without prolonging the session timeout
Date Thu, 17 Nov 2011 12:07:24 GMT
Les,

I'm really interested about your suggestion to use Shiro's native session
for my use case. I just didn't understand how I could do that. Can you
elaborate on you thoughts a bit?

/Bengt

2011/11/11 Bengt Rodehav <bengt@rodehav.com>

> 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 <lhazlewood@apache.org>
>
>> 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 <bengt@rodehav.com> 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 <bengt@rodehav.com>
>> >>
>> >> OK - thanks Manoj,
>> >> I'll take a deeper look in the code.
>> >> /Bengt
>> >>
>> >> 2011/11/9 Manoj Khangaonkar <khangaonkar@gmail.com>
>> >>>
>> >>> 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 <bengt@rodehav.com>
>> 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 <khangaonkar@gmail.com>
>> >>> >>
>> >>> >> 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 <bengt@rodehav.com>
>> >>> >> 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/
>>
>
>

Mime
View raw message