History | Log In     View a printable version of the current page. Get help!  
Issue Details (XML | Word)

Key: JBSEAM-2257
Type: Feature Request Feature Request
Status: Open Open
Priority: Minor Minor
Assignee: Shane Bryzak
Reporter: Jacob Orshalick
Votes: 16
Watchers: 11
Operations

If you were logged in you would be able to see more operations.
Seam

Raise a session expired and new session event on occurence

Created: 15/Nov/07 07:21 PM   Updated: 02/Apr/08 11:12 AM
Component/s: Security
Affects Version/s: 2.0.0.GA
Fix Version/s: 2.1.0.BETA1

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown
File Attachments: 1. Text File JBSEAM-2257.patch (2 kb)

Issue Links:
Dependency
This issue depends:
JBSEAM-2505 ServletContexts instance returns null... Blocker Closed
 
Duplicate
 
This issue is duplicated by:
JBSEAM-2178 Differ timed out session from new ses... Major Closed

JBoss Forum Reference: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=120893


 Description  « Hide
You have to make some assumptions here, but you can basically notify the user when the server session has ended with the following in a PhaseListener:

Code:

@Observer("org.jboss.seam.beforePhase")
public void beforePhase(PhaseEvent event)
{
  if(event.getPhaseId() == PhaseId.RESTORE_VIEW)
  {
    HttpServletRequest request =
      (HttpServletRequest) FacesContext.getCurrentInstance()
        .getExternalContext().getRequest();
            
    if(request.getRequestedSessionId() != null
           && request.getSession().isNew())
       Events.instance().raiseEvent("org.jboss.seam.sessionExpired");
...

Based on general cookie settings this will raise the event when the user still has the browser window open, the http session expired, and the user tries to access the app. If the user closes and reopens the browser to start the application, the event will not be raised. This of course makes the assumption that cookies expire when the browser session is ended (which is generally the case).

The org.jboss.seam.newSession event would simply change the condition to:

   if(request.getRequestedSessionId() == null
           && request.getSession().isNew())
      Events.instance().raiseEvent("org.jboss.seam.newSession");

This is generally useful for user notification on the login screen. Please see the forum reference for more information. Thanks.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order:
Jacob Orshalick [16/Nov/07 06:49 PM]
It would be nice if the event was initiated after the RESTORE_VIEW once the conversation has been initialized. This would allow the FacesMessages component to be used to easily add a message for user notification, i.e.

@Observes("org.jboss.seam.sessionExpired")
 public void sessionExpired(String message)
 {
         FacesMessages.instance().add("User session expired");
 }

The current workaround is described at:

http://solutionsfit.com/blog/2007/11/16/session-expired-messages-using-seam-security/

Florian Fray [08/Jan/08 11:48 AM]
This could be implemented quite easily via the class org.jboss.seam.contexts.Lifecycle .
Add a line "Events.raiseEvent("org.jboss.seam.newSession")" around ll. 188 (refering to 2.0.0.GA) and "Events.raiseEvent("org.jboss.seam.sessionExpired")" around ll. 238.
Well the Seam-Devs know where to add this, but maybe you'd like to patch this class before it is released.

IMHO this is a quite reasonable request and would like to have it. We had to do sth. similar to keep track of destroying the session.

Pete Muir [08/Jan/08 02:02 PM]
The point is to raise an event on session expiry, and not when the user closes the session themselves. I don't think your proposal achieves this?

Florian Fray [09/Jan/08 05:08 AM]
Pete, the Lifecycle.beginSession and .endSession is also triggered by the SeamListener,
which is implementing javax.servlet.http.HttpSessionListener.
So it is reacting precisely on Session-creation and -destruction.

You can approve this by following the code in org.jboss.seam.servlet.SeamListener.

Here's the related code for comfort-reasons:
org.jboss.seam.servlet.SeamListener
###
   ...
   public void sessionCreated(HttpSessionEvent event)
   {
      ServletLifecycle.beginSession( event.getSession() );
   }
   
   public void sessionDestroyed(HttpSessionEvent event)
   {
      ServletLifecycle.endSession( event.getSession() );
   }
   ...
###

org.jboss.seam.contexts.ServletLifecycle
###
...
   public static void beginSession(HttpSession session)
   {
      Lifecycle.beginSession( new ServletSessionMap(session) );
   }

   public static void endSession(HttpSession session)
   {
      Lifecycle.endSession( new ServletSessionMap(session) );
   }
...
###


Jacob Orshalick [09/Jan/08 08:43 AM]
What Pete is saying holds true here...

By simply placing the event in the beginSession and endSession, you cannot achieve the purpose of this request. Essentially the goal of this request is to raise an event when the session expires while a user is still active within the application (mainly for messaging purposes). The approach you suggest would raise the event always when a new session is started. The checks against the session id allow us to differentiate between a new session:

- where the browser was closed (the user expired the session) = new session and no session id (cookie gone)
- the session expired from user inactivity = new session and session id still present (cookie still present)

Another difficulty here is the message as described in the first comment. The timing of the event will be critical to ensure that the FacesMessages component exists in the context.

I will try to create a patch in the next few weeks (for this and a few other JIRAs I've requested). Been very busy with work lately ;)

Florian Fray [09/Jan/08 10:54 AM]
Okay, I've understood you want to check whether the session-id sent is still valid or not.

We've used this information (session created / session destroyed) differently, as we wanted to keep track of the currently logged in users.
Basically we've used the events org.jboss.seam.postAuthenticate and org.jboss.seam.loggedOut, but we also needed an event raised when the session expired, i.e. due to inactivity.
The code described just shows you that an invalid session-id has been used, but you won't really get the event at the time it expired, but with the next request (which could be days after the session expired).
The nasty drawback is that if the user does not send a request to the application again, you won't be able to recognize the session has expired.

IMHO this makes a huge difference. For our usecase it is crucial to get an event as soon as the session expired, not after the next request.

What about a third event, so we'd have:
"org.jboss.seam.expiredSession" (or sessionExpired)
"org.jboss.seam.newSession"
"org.jboss.seam.destroyedSession"



Pete Muir [09/Jan/08 11:55 AM]
Sure.

Thats what we've been trying to get you to understand - the difference between session expiry and destroying the session.

Jacob Orshalick [09/Jan/08 12:03 PM]
Your request sounds reasonable to me. I am +1 on the third event. I've seen requests for this on the forum as well for performing cleanup and auditing tasks (and I could see myself needing this at some point in the future ;-) ).

Jacob Orshalick [17/Jan/08 10:27 PM]
Need ServletContexts.instance().getRequest() to return the HttpServletRequest instance during a JSF request to avoid a context specific implementation.

Jacob Orshalick [01/Feb/08 10:33 AM]
Relies on JBSEAM-2505 to work within a servlet JSF request. The requested third event will be a separate patch (perhaps a different JIRA?).