Session Invalidation occurs via Web Command after Login using SSO. After Logout and Re-Login - Able to access pages from previous session - session

I have a Web Application that is deployed on Websphere 9. The application has a SAML servlet (SSO Login) and using Web Commands subsequent operations are performed on the application. In one of the Web Commands, the session invalidation code runs.
invalidateAllWebAppSessions(request)
public static void invalidateAllWebAppSessions(HttpServletRequest req) {
try {
IBMSessionExt sessExt = (IBMSessionExt) req.getSession();
if (sessExt != null) {
sessExt.invalidateAll(true);
}
} catch (IllegalStateException e) {
LOG.error("Exception in invalidating Session", e);
}
}
This invalidation code runs perfectly and I have verified using request.getSession(false) == null that the session has been invalidated successfully.
Afterwards when I am logging out and logging back in (The webcommand runs again and previous session is invalidated and new session is created.) Now when I long press the browser back button and try moving to any of the screens of the previous session, I am able to directly access that screen. This should not be accessible as I have invalidated previous session.
If I directly invalidate existing session in the SAMLServlet there is no problem and my issue is resolved, but if I invalidate session in web command then the issue remains.

Related

Spring Security deletes session form the database when user logs out

I'm implementing spring security in my project and have used mysql database to store sessions. Everything works fine but when the user logs out, its session is also deleted from the database which I do not want. I only want session to be invalidated but not deleted from the database.
On debugging, I found :
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
Assert.notNull(request, "HttpServletRequest required");
if (invalidateHttpSession) {
HttpSession session = request.getSession(false);
if (session != null) {
logger.debug("Invalidating session: " + session.getId());
**session.invalidate();**
}
}
if (clearAuthentication) {
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(null);
}
SecurityContextHolder.clearContext();
}
This code is from SecurityContextLogoutHandler class.
Further, the code execution goes in:
private final class HttpSessionWrapper extends HttpSessionAdapter<S> {
HttpSessionWrapper(S session, ServletContext servletContext) {
super(session, servletContext);
}
#Override
public void invalidate() {
super.invalidate();
SessionRepositoryRequestWrapper.this.requestedSessionInvalidated = true;
setCurrentSession(null);
clearRequestedSessionCache();
**SessionRepositoryFilter.this.sessionRepository.deleteById(getId());**
}
}
The last line of the function deletes the session which I do not want.
My question is can I stop spring security from deleting sessions from the DB when user logs out or this is how spring security works?
Is there any specific reason why you don't want to delete session from DB once user log's out ? This is pretty much common behavior. Session is representing your logged in client. Once client log's in (provide valid credentials, password with username for example) session ID is created and sent to client. This session ID is representing valid logged in connection. On subsequent request's from this client he will only send this session ID inside header, your app will check if this session ID is stored inside valid session's (your DB for example) and if it is this request is considered authenticated (therefore client doesn't have to send his credential's which has to be verified with each request, he is only sending session ID). Once client log's out the session ID is invalidated since with logout his connection is no longer authenticated. Therefore yes this is how spring security work's, there is no need to persist invalidated session's. You would also have to implement custom mechanism for clearing session's from DB (when will be session cleared if not at time of user logout). Also you might consider to use session pool inside memory instead of DB.
Edit: i don't how spring check's valid session's in case of DB session pool but at some time it has to access DB read all session's so it can find out which session ID's are valid (i guess this is done for each after - login request at least). How could be invalidated session in your case be persisted inside database session pool when valid session's are defined by that pool at same time ?

Redirection stopped working after sometime on Production

I am facing a very strange issue only on the Production server.
I am using SAP Hybris which use Spring security.
When the user is trying to access any secure URL of the site, it gets redirected to the login page, once he logging to the system it redirects back to the URL he was trying to access before. This is expected behavior.
Now on production storefront nodes, it's working fine for some time(Say about 30minute) when I restart the server. And then it stopped working. After login user redirects to the homepage instead of the secure URL he was trying to access.
Note: It's working absolutely fine in all lower environment(Local, DEV, Stage etc).
Any idea? Your help would be appreciated!!
Edit:- This issue happens even I directly access my application node(tomcat server) using IP address, So I don't think it's related to LB/cache server/web server/any cluster setting.
It's been long time, so I forgot the exact cause of the issue. I think I was able to regenerate it in my local and fixed it by overriding forceDefaultTargetUrlBySession method of StorefrontAuthenticationSuccessHandler. Here is my committed code.
protected void forceDefaultTargetUrlBySession(final HttpServletRequest request, final HttpServletResponse response)
{
//if redirected from some specific url, need to remove the cachedRequest to force use defaultTargetUrl
final RequestCache requestCache = new HttpSessionRequestCache();
final SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest != null)
{
if (savedRequest.getRedirectUrl() != null && StringUtils.contains(savedRequest.getRedirectUrl(), PASSWORD_UPDATE_PAGE_PATH))
{
requestCache.removeRequest(request, response);
}
}
}

How to invalidate session in Vaadin 7 aplication?

I've got a Vaadin 7 application which authenticates against ldap with a security-domain configured in my server's standalone.xml (jboss eap6). Everything works fine until i try to log out.
In my Vaadin UI i've got a logout method:
public void logout(){
VaadinService.getCurrentRequest().getWrappedSession().invalidate();
this.close();
}
When i execute the method i get the message:
SESSION EXPIRED Take note of any unsaved data, and click here or press ESC key to continue.
But once i do it refreshes the page and i'm still logged in
Is there anything else i need to do to properly close the session?
Thanks!
I think your problem is that you can't close the application because you've just invalidated the session. Try closing the application before you invalidate the session. Something like this:
public void logout(){
HttpSession ses = VaadinService.getCurrentRequest().getWrappedSession();
this.close();
ses.invalidate();
}
The problem wasn't with the way i was closing the session in Vaadin. The problem is that Jboss keeps the ldap user authenticated. So after i closed the session with
public void logout(){
VaadinService.getCurrentRequest().getWrappedSession().invalidate();
this.close();
}
i would somehow get a new session id but the server kept the user authenticated. I solved it using the same snippet to logout but managing the ldap login from within my application. Since i don't use the jboss security-domain and instead use my own login screen to go against ldap by code the problem is gone.

How do I change session timeout for a single page under Tomcat running a Spring security controlled application?

Part of my application has a single page view for an overhead status board. Access to the server that runs the overhead display is in an access controlled location that only a few key people have access to. The problem I am encountering is that the session expires after a set amount of time, necessitating someone physically going to the server and reloading the page. Needless to say this creates some problems when the key people aren't around.
This application runs under Tomcat, and security is controlled via Spring security. How would I go about changing the session timeout for this page only?
[edit]
I've taken the approach that #sotirios-delimanolis suggested. Although I still need to find an elegant way to reverse the extended session timeout if the user navigates to this page then navigates away, this appears to work for me.
Following is the relevant snippet of code that implements this:
#RequestMapping(value="BigBoard", method = RequestMethod.GET)
public void getBigBoard(HttpServletRequest request, Model model) {
HttpSession session = request.getSession();
session.setMaxInactiveInterval(604800);
I don't know how your page is accessed, by controller, resource provider, etc. but you would have to add a Servlet, Filter, HandlerInterceptor or handler method somewhere in the processing of that request that basically did the following
int seconds = ...; // timeout
request.getSession(true).setMaxInactiveInterval(seconds);
That session now has the specified timeout before the container invalidates it.
Note that if the user goes to some other page somehow, the timeout for their session will remain what you set above unless you change it.
Make the page refresh itself every now and then (using <meta http-equiv="refresh" content="60">) or add some Ajax polling to avoid session timeout.

Extjs 4 Session Management

I am having web based application in which user session has to be managed management.
In app.js I have used launch config as :
launch: function(){
Ext.create('myproject.view.LoginForm')
}
LoginForm : will show log in dialog and invoke login controller for communicating with server for authenticating the credentials provided by the user.
So when ever user refreshes the page Extjs is asking for log in that is because of I am not checking the session in here, How should be the session details stored in Extjs client and check to avoid prompting the log in unless user has log-out ? and How to manage user session ?
User identity and session information must be stored server side. Typically a cookie is set once the user authenticates successfully so as not to prompt the user again. This cookie is sent from the server and is stored in the browser automatically and sent back to the server for inspection on page refresh. Server should validate the cookie if OK allow user to proceed.
Per #existdissolve comments below
In your launch method, simply run a a session check before you create the login form. Whether this is cookie checking or a request directly to the server, the result of the session check can then trigger the creation of the login form, or whatever other logic you have for creating the rest of the application
Session Management can be done using
Inside login controller
// Storing user details in session / cookies
Ext.util.Cookies.set("key", value);
On logout button
// remove user details from cookies
Ext.util.Cookies.set("key", value);
In App.js
autoCreateViewport: false,
launch: function(){
var key= Ext.util.Cookies.get("key");
if (key=== undefined || key== 'null' || key== null || key.length <= 0){
// load login UI as user is not logged in
Ext.create('app.view.LoginForm');
}
else {
// load main UI as user is already logged in
Ext.create("app.view.Viewport");
}
}

Resources