Search code examples
jsfservletsglassfishback-buttonviewexpiredexception

Preventing ViewExpiredException when clicking broswer back button after session invalidation


I am trying to figure out how to prevent Session Fixation on an JSF login form in Glassfish 3.1. It was easy to do with Servlets, so I am trying to do the same with JSF (based on this question: Retrieving session ID value from a JSF request):

FacesContext fCtx = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) fCtx.getExternalContext().getSession(false);
session.invalidate();   
fCtx.getExternalContext().getSession(true); 

It seems to work, but when I click the browser's back button and re-enter login details I get:

javax.faces.application.ViewExpiredException: viewId:/index.xhtml - View /index.xhtml could not be restored.

It works again only after "refresh" and resend.

What could be the reason for that?


Solution

  • You need to instruct the browser to not cache the JSF pages. Create a Filter which is mapped as @WebFilter(servletNames={"facesServlet"}) and does the following job in doFilter() method

    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
    response.setDateHeader("Expires", 0); // Proxies.
    chain.doFilter(req, res);
    

    This will force the browser to fire a brand new GET request on back button press. It would otherwise only return the page from the cache and the form submit will then fail because the server side view state is been lost with the session invalidation.