5

Regarding Servlet 3.0 programmatic security, when a session times out there is no way to invoke HttpServletRequest#logout().

Does the user remain logged into JAAS?

If so, what is best practice to handle logging out of JAAS after session times out?

How does the container handle the user's subsequent request to login again and create a new session after session timeout?

As an aside, what are the pros and cons of using the following three approaches to handle session timeout when using Servlet 3.0 programmatic security:

  1. HttpSessionListener#sessionDestroyed()
  2. Make the @ManagedBean @SessionScoped LoginManager implement HttpSessionBindingListener and do something in valueUnbound.
  3. Annotate a method in LoginManager with @PreDestroy.

Any other suggested approaches/ best practices advice would surely be appreciated.

Patrick Garner
  • 3,201
  • 6
  • 39
  • 58
  • "Core Java Server Faces" p. 525 indicates "Currently, there is no specification for logging off or for switching identities when using container-managed security." – Patrick Garner Feb 28 '12 at 03:37
  • I've also come across a couple of blog rants about J2EE security, complaining that an invalidated session is a poor substitute for formal logout, but the blogs were older, written before Servlet 3.0, which provides a means to logout programmatically. – Patrick Garner Feb 28 '12 at 03:41
  • Obviously your CJSF edition predates Servlet 3.0. – user207421 Jul 17 '12 at 22:43

2 Answers2

3

There is a statement somewhere in the Servlet specification to the effect that session invalidity corresponds precisely to the state where there is no Principal in it. This is the key. logout() and timeout both invalidate the session, and invalidating the session removes the Principal from it, and all its value bindings.

All that JAAS really does is allow LoginModules to accumulate Principals in a Subject, both for the user and his roles. All that the JAAS logout() method really needs to do is clear the Subject of the Principals that were added by the same module's login(), or more probably commit(), method, and this is really just for total security if you have added things like private credentials to the Subject. As logout() won't be executed by the same instance as login()/commit(), that removal has to be based on principal class rather than on an internal collection of principals.

The JAAS logout() isn't called when the session expires, but as the Principal is removed from the session that shouldn't really matter to anybody.

If you want to track session termination for some other reason, e.g. logging, make your user bean a session binding listener and log the termination as a logout in the valueUnbound() method: this is 100% reliable in my experience.

To answer your other questions, there isn't such a state as 'logged in to JAAS': JAAS provides a login/logout service to the container, not to itself; and a new login is a new login, into a new session, whether or not the previous one expired.

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
user207421
  • 305,947
  • 44
  • 307
  • 483
  • +1 for a succinct (correct) answer =) A lot of offensive comments were removed from this post rendering some of the (removed) answers incoherent in tone. All's well that ends well. – earcam Jul 18 '12 at 00:02
  • Thanks @EJP. Interestingly, if I set a breakpoint after invocation of request.logout() I can see that the session is _not_ invalidated, although the Principal _is_ removed from the session. Upon logging back in the JSESSIONID does not change & the session object remains the exact same instance (e.g. @15961), which is a bit unsettling. Using session.invalidate() in addition to or in lieu of request.logout(), of course, causes JSESSIONID & session object to be changed. This is on JBoss AS7. Most importantly, Principal is removed as you said regardless of which of the two methods is invoked. – Patrick Garner Jul 18 '12 at 04:05
  • @PatrickGarner Well that all that the documentation of HttpServletRequest.html.logout() says that it does. Session.invalidate() does the invalidating, but it doesn't affect the current request or its principal, so if you just use that you can still display things as though the user was logged in. You have to call them both. Strange business really. – user207421 Jul 18 '12 at 08:23
2

Session management is not directly linked to JAAS.. and session management really depends on your container.

In Jetty 8, session management is handled by the SessionManager (at the context level) and SessionIdManager (at the server level).

The browser sends the session id to the server. The class implementing the SessionManager validates the session Id. If the session is expired, the session is invalidated and removed, and session listeners are notified.

I am not sure why you then need to 'logout' the user then but you should be able to hook your logout on the listeners.

'Staying logged in JAAS' may not mean much on your container. Jetty does not have a user/principals/subjects cache, so you do not 'stay logged in' unless you implement a cache yourself, as we did.

The JAAS module simply provides authentication and authorization; nothing else.

ADD

When the session is expired, the server sends a 302 back and redirects to the login page. The form submit on the page calls the Login module (which may be a JAAS Module) and upon successful authentication creates a new session and session id which is sent back to the browser usually via the mean of a cookie ( or URL rewriting).

Unless your app handles a single context id for all your contexts, I do not think you should perform any type of programmatic logout when a session expires; you may 'invalidate' an user which still has a valid session in another context.

b75.
  • 94
  • 2
  • I don't know what's inside the guts of JAAS. I don't know how the web container interfaces with JAAS e.g. where the Subjects, Principals and Groups are stored, what actually happens when HttpServletRequest#logout() is invoked vs. when the session times out. Does the housekeeping performed when HttpServletRequest#logout() is invoked also get performed by the container if the session times out? If not, why is it not necessary in such circumstance? – Patrick Garner Mar 11 '12 at 04:02
  • After reading the Servlet 3.0 spec. and JAAS spec. and JEE 6 spec. I don't know the answers to the above questions and I'm hoping that someone can point me to documentation or dev-list threads or perhaps even JBoss/Tomcat/Jetty/Glassfish design documents or source code snippets that show what happens to Subject, Principal, and Group instances when the session times out. It would be great to know what happens to these objects when HttpServletRequest#logout() is invoked as well. The differences, if any, between how log out is handled under the two circumstances would be great. – Patrick Garner Mar 11 '12 at 04:09