Sessions, logout, sessionScope and userScope
One of the common misconceptions I’ve come across with XPages developers is that sessionScope will contain the information for the current logged on user. It can, but it may not. And discussions with Serdar Basegmez and Russ Maher over the last couple of days have helped me understand things yet further.
Let’s back up here and cover some very important points:
- XPages applications that require authentication, first hit the Domino HTTP server, which prompts for authentication and issues a SessionID cookie to the browser. Any HTTP or XPages interaction with the server from that point onwards uses the SessionID cookie to identify where the request comes from and keep the authenticated session active. But each XPages application uses its own ClassLoader, so all the scopes – requestScope, viewScope, sessionScope and applicationScope – only hold data for the current NSF. sessionScope holds data for the session for the current application only.
- Moreover sessionScope is for the browser session, not the user session.
- When the user logs out, via a Login or Logout Node from the Extension Library or a redirection to a “/?logout” URL. This clears only the authenticated credentials. Log out and don’t close the browser, check your cookies and you’ll see the SessionID cookie is still there.
What the first point means is that logging into an application from two different browsers as the same user means you’re using separate sessionScope maps. You’re not sharing the same sessionScope map for both browser sessions.
Add those last two points together, and if you set sessionScope variables, just do an HTTP logout, don’t close the browser, go back to an application that requires authentication, log in as a different user: the previous sessionScope variables are still available.
There are a couple of options.
You can clear the sessionScope map or invalidate the session – thanks to Russ for the sample code - facesContext.getExternalContext().getSession(false).invalidate(). But factor in point one from above and you’ll realise that these two mean you can only clear the session for XPages in the current NSF. You don’t have access to any other NSF. So if you log back in, you will have removed sessionScope for the application you ran the SSJS / Java code in, but not in any other application the user accessed during that browser session.
What Serdar did notice was that if you log out – regardless of clearing sessionScope by whatever means – and then go to a page in the database that allows Anonymous access, the SessionID cookie is regenerated. That means new sessionScope maps will be used across the server. But that may not be a desirable option for your applications.
It may be possible to clear the session via a custom servlet, but that’s not been investigated.
So how do you get a unique session for the user regardless of where they’re logging on from? The solution is to put a map into applicationScope where the key is the current user’s effective user name. A userScope. Which is what Nathan added in the last couple of days to OpenNTF Domino API. Many developers may have been doing something similar, or re-initialising sessionScope if the current user changes. But this gives an easy scope accessible based on user name. But because it’s added to applicationScope, it’s still per application. It’s not a userScope shared across the whole server. Of course that would be possible…