• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

Proper session timeout redirect

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm trying to implement a good way to handle a session timeout -> redirect. I'm using JSF 2.0, and have a basic HttpSessionListener and web.xml timeout limit, but I can't figure a way to redirect from the sessionDestroyed method.

The other thread I found on this indicated that redirecting on a session timeout is "bad design". But that's short sighted, there are many reasons to do it, consider your banking web site.

This is as close as I've come, with a faces context that maintains itself past the session destroy, but the redirect still doesn't work:



We initially used the deprecated:

<meta name="sessionTimeout" http-equiv="refresh" content="#{session.maxInactiveInterval};url=....." />

But we can't continue to use that, because a page that uses ajax won't refresh that time out.



So what is the conventional way to handle this?

Thanks.
 
Saloon Keeper
Posts: 28713
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You should not attempt to store a copy of FacesContext in anything longer-term than method scope. FacesContext is created on each JSF page request and is effectively destroyed once the response has been sent. All you're doing is holding onto a dead object. It's also not a global object despite the fact that you reference it by class. Effectively, each user has their own distinct FacesContext, which, like I said, exists only for the duration of that particular request/response cycle. And even there, only within the thread context - it's explicitly documented that should a request handler spawn threads (usually a bad idea), those threads also cannot reference the FacesContext.

Personally, I don't like being forced to another page. I'd much rather have a login pop up and once re-logged, be able to return to whatever I'd been doing. However, since the session has been destroyed, that's an "iffy" thing to do in most cases, since you'd have to faithfully reconstruct the session for that page. But we all have our preferences.

As far as AJAX goes, every time an AJAX request is made, that counts as a server hit and therefore the session timeout countdown would reset. So you could actually use AJAX as a "keep-alive". This is, of course, providing that the AJAX request was made to the same webapp as the one whose session would have otherwise timed out.

I'd go so far as to say that the #1 weak spot in JSF is timeouts and especially the dreaded "View Context cannot be restored". Some improvements have been added to JSF2, but there's a lot more to be done.
 
Alex Rex
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the info, that's very helpful. So supposing I wanted to automatically redirect to the log on page when the session expires, how would I do that?
 
Tim Holloway
Saloon Keeper
Posts: 28713
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Alex Rex wrote:Thanks for the info, that's very helpful. So supposing I wanted to automatically redirect to the log on page when the session expires, how would I do that?



Horribly, if you do it like most people.

J2EE defines a built-in security system. If you use that when not logged in to access a protected URL (as defined in web.xml), the server will automatically intercept the request, put it on hold, present a login screen (assuming you defined form-based authentication in web.xml), and - assuming the login was successful - then resume the original web request, sending the user to the page he/she requested.

However, in real life, a depressingly large number of people don't use that system, invent their own, supply their own login page processors (aided and abetted by numerous examples in Java books), and end up with an application that a 5-year old could hack into in under 15 minutes.

I'm dead serious. I've been working with J2EE since before JSPs were invented, seen innumerable "do it yourself" security systems, and most of them had all the impenetrability of wet cardboard. Not one of them could resist a halfway-determined attack, even the military ones. Which is why I don't recommend DIY security. The J2EE standard container-managed system was designed and vetted by security professionals, not people who were instructed to slap in security as part of the bigger project. It does most of its work by preventing access to the application by unauthorized users at the server level - unauthorized requests never get passed to application code at all, which means that the app doesn't have to worry about major security loopholes in the application code.

It also supports bookmarking, since the signon process intercepts and restores URL requests. However, if you absolutely must force people to a "home" page after signon, you can also do that. Just redirect the first request that comes in with a non-null userID. There is no actual "login event" to listen to, since in a single-signon environment, some other application might have been the one that caught the login.
 
Alex Rex
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks again. We're a little late in the game for switching our authentication model, but I'll take that advice to heart in the future.

I've already got it set up to forward on the next request, but what I'm asking is for it to be automatically served. I know this can be achieved with the meta header:


but that doesn't play well with ajax, so that option is out.

This is something I know can be done, because every banking website does it. Your session times out and it redirects you to a login page without you having to request another page. This is a good thing for a page with sensitive information on it. So are they doing it the old meta tag way, or is there a better way I can do that?
 
Tim Holloway
Saloon Keeper
Posts: 28713
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, I don't know where you got that meta tag from. It's not one of the standard ones, and the best I can determine is that maybe .Net uses it. Java session timeout is set in web.xml, not on the client where it could be hacked.

At the risk of showing an attitude (who, me?), most of the public-facing financial sites I've seen lately are built on Microsoft platforms, make gratuitous use of javascript, and often pop-up windows as well. The Flash-heavy ones I avoid entirely.

One way you can force a logoff from the client side is just to run a javascript that maintains a timer and sends an AJAX logoff request to the server when the interval has expired. But see above about client-side session timeout issues.

On the server, I believe a filter can check incoming URLS, and if there's no established session, just do a straight (non-JSF) redirect (forward) to the JSF login page. Since a session timeout destroys the session, that should work.

One thing, however, if you do have AJAX requests spontaneously popping in from an otherwise idle page, like I said, they'll reset the session timeout. There's no real cure for that except to either have them talk to a different app (if possible), handle their own timeout (and again, see above), or try and maintain an internal timeout timer that only gets reset from the non-AJAX URL requests.
reply
    Bookmark Topic Watch Topic
  • New Topic