title: Redirecting a user after container-based login using JAAS and JSF
body: <p>I'm trying to accomplish a <code>jsf2</code>-based form login where a user can go straight to his chosen URL after being redirected to the <code>login-page</code>. How can this be accomplished? My current settings are as following (using <code>glassfish 3</code>)</p>
  
  <p>Web.XML</p>
  
  <pre><code>&lt;login-config&gt;
      &lt;auth-method&gt;FORM&lt;/auth-method&gt;
      &lt;form-login-config&gt;
          &lt;form-login-page&gt;/login.jsf&lt;/form-login-page&gt;
          &lt;form-error-page&gt;/login.jsf&lt;/form-error-page&gt;
      &lt;/form-login-config&gt;
  &lt;/login-config&gt;
  &lt;security-constraint&gt; //(omitted) all pages except login.jsf requires login &lt;/security-constraint&gt;
  </code></pre>
  
  <p>Session scoped managed bean handling login</p>
  
  <pre><code>public String login(){
      try{
          FacesContext context = FacesContext.getCurrentInstance();
          HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
          request.login(username, pwd);
          loggedInUser = userBean.findByLogin(username);
          username = null;
          pwd = null;
          //context.getExternalContext().redirect((String)request.getAttribute("from"));
          return "/index?faces-redirect=true";
  
      } catch(Exception e){
          logger.log(Level.FINE, "login failed: {0}", e.getMessage());
          JsfUtil.addErrorMessage("Login failed");
          return null;
      }
  }
  </code></pre>
  
  <p>From another question i got the tip to use a filter instead of the contained handled redirect to the login page, and store the URL before redirect as an attribute in the request like this:</p>
  
  <pre><code>public class LoginFilter implements Filter {
      private String loginPage = "/login.jsf";
  
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
      }
  
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
          ServletException {
          if ((request instanceof HttpServletRequest) &amp;&amp; (response instanceof HttpServletResponse)) {
              HttpServletRequest httpServletRequest = (HttpServletRequest) request;
              HttpServletResponse httpServletResponse = (HttpServletResponse) response;
              // is session expire control required for this request?
              if (httpServletRequest.getUserPrincipal() == null) {
                  // User is not logged in, redirect to login page.
                  httpServletRequest.setAttribute("from", httpServletRequest.getRequestURI());
                  httpServletResponse.sendRedirect(loginPage);
              }
              else
                  filterChain.doFilter(request, response);
          }
      }
  
      @Override
      public void destroy() {
      }
  
  }
  </code></pre>
  
  <p>With the url-pattern set to the same as the sum of all security constraints. The problem is how to combine this with the container based login. Leaving login-config auth method as FORM causes the filter to not be executed. Removing it sets the auth-method to BASIC which 1. causes my form to not appear, and 2. httpServletRequest.getUserPrincipal() is automatically set by the web browser to a cached value, so even if the filter is executed, the if-statement will always be false. From what i know, there is no way to keep the browser from doing this, even if the session is invalidated.</p>
  
  <p>Is there any solution to this?</p>