带有请求头的Tomcat身份验证



我有一个在Tomcat7上运行的web应用程序。目前用户通过JDBCRealm使用密码登录。

在我的组织中有一个身份验证服务器。用户向该服务器发送HTTP请求,服务器以某种方式对其进行身份验证,然后使用自定义HTTP标头将请求转发到我的应用程序,该标头指定经过身份验证的用户名(无密码)。

我想使用这种机制对我的应用程序的用户进行身份验证,同时保留JDBC领域。当用户向/login发送请求时,他们的请求将使用标头进行身份验证,并且他们将被重定向到主页,就像他们使用标准j_security_check表单登录一样,但不必提供密码。

以下是我到目前为止的想法:

@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");
  }
}

当我为JDBCRealm提供了正确的密码,但密码在过滤器中不可用时,这就起作用了。

更新:我最终用一个自定义阀门解决了这个问题:

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<String> roles = ... // From req
        session.setPrincipal(new GenericPrincipal(username, null, roles));
    }
    req.setUserPrincipal(session.getPrincipal());
    getNext().invoke(req, res);
}

我从一个稍后调用的过滤器中进行重定向。

我还差三分就可以发表评论了,所以我必须根据给定的信息回答,用猜测填补一些空白。

您可以通过子类化javax.servlet.http.HttpServletRequestWrapper.来实现"身份验证"

重写getRemoteUser()和getUserPrincipal(),以便它们返回经过身份验证的用户的用户名,以及一个Principal对象,该对象基本上可以是您想要创建的任何对象。JMXPrincipal应该很方便使用。您可能还应该重写getAuthType()以返回HttpServlet请求.FORM_AUTH,从而使所有内容都很好地网格化。并根据Javadoc实现一个快速注销()方法,该方法表示"在请求中调用getUserPrincipal、getRemoteUser和getAuthType时,将null设置为返回的值。"

然后,在过滤器中,将传入的HttpServlet请求包装在包装器对象中,并将包装器对象传递到chain.doFilter().中

如果你想获得灵感,你可以在包装器上覆盖login()方法,它接受任何(或null)密码,并创建将由getRemoteUser()、getUserPrincipal()和getAuthType()返回的内部实例变量。

相关内容

  • 没有找到相关文章

最新更新