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:
This is generally useful for user notification on the login screen. Please see the forum reference for more information. Thanks.
Description
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.
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");
}
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/
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.
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?
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() );
}
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) );
}
...
###
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 ;)
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 ;)
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"
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.
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 [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 ;-) ).
Need ServletContexts.instance().getRequest() to return the HttpServletRequest instance during a JSF request to avoid a context specific implementation.
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?).
@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/