title: Tomcat authentication with request headers
body: <p>I have a web app running on Tomcat 7. Currently users login with passwords through JDBCRealm.</p>
  
  <p>In my organization there's an authentication server. Users send HTTP requests to that server, the server authenticates them somehow, and then forwards the request to my app with a custom HTTP header that specifies the authenticated username (no password).</p>
  
  <p>I'd like to use this mechanism for authenticating users to my app, while keeping the JDBC realm. When users send a request to <code>/login</code>, their request will be authenticated using the headers, and they'll be redirected to the main page as if they logged in using the standard <code>j_security_check</code> form, but without having to provide a password.</p>
  
  <p>Here's what I came up with so far:</p>
  
  <pre><code>@WebFilter("/login/*")
  public class LoginFilter implements Filter {
  
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
  
      HttpServletRequest httpRequest = (HttpServletRequest) req;
      HttpServletResponse httpResponse = (HttpServletResponse) res;
  
      String username = ... // Extract username from httpRequest, not an issue
  
      httpRequest.login(username, "???"); // Need to provide a password!
  
      httpResponse.sendRedirect(httpRequest.getContextPath() + "/pages/home.xhtml");
  
    }
  
  }
  </code></pre>
  
  <p>This works when I provide the right password for JDBCRealm, but the password is unavailable in the filter. </p>
  
  <p><strong>Update:</strong> I ended up solving this with a custom valve:</p>
  
  <pre><code>public class LoginValve extends ValveBase {
  
      @Override
      public void invoke(Request req, Response res) throws IOException, ServletException {
  
      if (!req.getRequestURI().equals(req.getContextPath() + "/login")) {
          getNext().invoke(req, res);
          return;
      }
  
      Session session = req.getSessionInternal();
  
      if (session.getPrincipal() == null) {
          String username = ... // From req
          List&lt;String&gt; roles = ... // From req
          session.setPrincipal(new GenericPrincipal(username, null, roles));
      }
  
      req.setUserPrincipal(session.getPrincipal());
  
      getNext().invoke(req, res);
  
  }
  </code></pre>
  
  <p>And I do the redirect from a filter that's called later.</p>