Search code examples
jsfhttp-redirectspring-securitytimeoutviewexpiredexception

jsf spring security session timeout viewExpiredException


I have the following problem with the timeouts in Spring Security with JSF:

I've customized the sessionmanagement filter so that the user is redirected to the invalidSessionUrl just if the requested page is secured (i.e. if it is allowed just for authenticated users). The custom code I put into the session management filter provided by Spring Security is:

if (invalidSessionUrl != null) {
     String pagSolicitada = UtilSpringSecurity.extraerPagina(request);
     if ( UtilSpringSecurity.paginaAutenticada(pagSolicitada ) ) {
          request.getSession();
          redirectStrategy.sendRedirect(request, response, invalidSessionUrl);
          return;
     }
     //the requested page doesn't require the user to be authenticated
     //so i just skip this filter and continue with the filter chain
     chain.doFilter(request, response);
     return;
}

The method "UtilSpringSecurity.extraerPagina(request)" returns the requested page this way:

public static String extraerPagina (HttpServletRequest request) {
     String uri = request.getRequestURI().toLowerCase();
     String cPath = request.getContextPath().toLowerCase();
     // uri = cPath + pagina
     int longCPath = cPath.length();
     String pagina = uri.substring(longCPath);
     return pagina;
}

And the method "UtilSpringSecurity.paginaAutenticada(pagSolicitada)" returns true if the the param is a page that requires the user to be authenticated (I do the check with IFs, considering the intercept-url elements of my xml security config file which have the attribute access="isAuthenticated()"):

public static boolean paginaAutenticada (String pagina) {

     if (pagina.startsWith("/faces/paginas/administracion/") || pagina.startsWith("/faces/paginas/barco/") ) {
          return true;
     }
     return false;
}

This solution works, but it has just one problem:

If I leave the browser staying idle at a page until the session timeout expires, and then I request the same page, then I get a "viewExpiredException". This is because the filter worked well, it bypassed the redirection to the invalidSessionUrl, but as the session expired anyway, then I get that exception trying to re-render the same page.

If I request any other unsecured page when the session timout has expired, it works well, it redirects correctly to the page and I don't get the viewExpiredException.

Anyone knows how to solve this?

Thank you in advance.


Solution

  • Finally I solved it. It's a JSF issue, nothing to do with Spring Security.

    I've overriden the restoreView method of jsf this way:

    @Override
    public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
         UIViewRoot root = wrapped.restoreView(facesContext, viewId);
         if(root == null) {
              root = createView(facesContext, viewId);
         }
         return root;
    }
    

    Now the problem is that if the page had parameters, I lost them when I do the post to the recently created view, but that's another distinct issue (PRG pattern) dealing again with JSF.