使用mod_jk将用户名和客户端证书从apache传递给tomcat

使用mod_jk将用户名和客户端证书从apache传递给tomcat,apache,tomcat,authorization,mod-jk,Apache,Tomcat,Authorization,Mod Jk,我想通过ssl证书(针对自动化)或openid(针对人,我使用auth0作为提供者)对web服务进行身份验证。web服务在tomcat容器中运行,该容器位于ApacheWeb服务器后面,使用jk。web服务器已经使用auth0(使用mod_auth_openidc)对其他路径的用户进行身份验证,并且仅通过https可用。我还有一个数据库,它当前将auth0提供的用户名映射到角色(在apache中用于授权) 我希望具有以下功能: 计算用户名 如果apache已经登录用户,请使用用户名 如果请求中

我想通过ssl证书(针对自动化)或openid(针对人,我使用auth0作为提供者)对web服务进行身份验证。web服务在tomcat容器中运行,该容器位于ApacheWeb服务器后面,使用jk。web服务器已经使用auth0(使用mod_auth_openidc)对其他路径的用户进行身份验证,并且仅通过https可用。我还有一个数据库,它当前将auth0提供的用户名映射到角色(在apache中用于授权)

我希望具有以下功能:

  • 计算用户名
    • 如果apache已经登录用户,请使用用户名
    • 如果请求中使用了客户端证书,请使用DN作为用户名
    • 如果以上都没有,那么重定向以便apache进行身份验证
  • 找出角色
    • 根据用户名进行数据库查找
  • 我发现我可能需要编写一个过滤器,从中我似乎可以从请求中获得证书和用户名。我编写了以下代码:

    package com.kodekonveyor.realm;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    public class KKAuthorizationFilter implements Filter {
    
    private ServletContext context;
    
    @Override
    public void init(FilterConfig fConfig) throws ServletException {
        this.context = fConfig.getServletContext();
        this.context.log("KKAuthorizationFilter initialized");
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String user = httpRequest.getRemoteUser();
        Object cert = httpRequest.getAttribute("javax.servlet.request.X509Certificate");
        this.context.log("user:"+user);
        this.context.log("cert:"+cert);
        chain.doFilter(request, response);
    
    }
    
    }
    
    但是,当我尝试使用当前已通过身份验证的用户或客户端ssl身份验证访问servlet时,用户和证书都记录为null。我怀疑我必须进行更多的apache配置才能使其正常工作。 测试servlet位于tomcat中的/servlet/servlet

    我有以下apache配置(brewity省略了部分)

    DocumentRoot/var/www/repo
    #省略了正确的OIDC配置
    ServerName myhost.mydomain.com
    DBDriver pgsql
    #省略了其他DBD配置
    JkMount/servlet*worker1
    目录索引关闭
    发动机熄火
    AuthType openid连接
    不允许超限
    AuthzDBDQuery“正确的数据库查询”
    需要dbd组allrepo
    日志级调试
    目录索引关闭
    发动机熄火
    不允许超限
    #省略了正确的letsencrypt配置
    
    原因是,如果在Location(或者也可能是Directory)指令中有JkMount,则所有其他自动化和授权(甚至所有其他?)指令都无效

    位于/servlet的servlet的示例工作配置:

    <Location "/servlet*">
            JkMount  worker1
    </Location>
    <LocationMatch /servlet.*>
        DirectoryIndex off
        RewriteEngine Off
        AuthType openid-connect
        AllowOverride None
        LogLevel debug
        Require valid-user
            SSLOptions +StdEnvVars
            SSLOptions +ExportCertData
            SSLVerifyClient require
    </LocationMatch>
    
    
    JkMount worker1
    目录索引关闭
    发动机熄火
    AuthType openid连接
    不允许超限
    日志级调试
    需要有效用户
    发展+标准
    SSLOptions+ExportCertData
    SSLVerifyClient要求
    
    另一种可能的解决办法:

    <LocationMatch /servlet.*>
           SetHandler jakarta-servlet
           SetEnv JK_WORKER_NAME worker1
           DirectoryIndex off
           RewriteEngine Off
           AuthType openid-connect
           AllowOverride None
           Require valid-user
           LogLevel debug
            SSLOptions +StdEnvVars
            SSLOptions +ExportCertData
            SSLVerifyClient require
    </LocationMatch>
    
    
    SetHandler jakarta servlet
    SetEnv JK_WORKER_NAME worker1
    目录索引关闭
    发动机熄火
    AuthType openid连接
    不允许超限
    需要有效用户
    日志级调试
    发展+标准
    SSLOptions+ExportCertData
    SSLVerifyClient要求
    
    请参阅以进行讨论

    <LocationMatch /servlet.*>
           SetHandler jakarta-servlet
           SetEnv JK_WORKER_NAME worker1
           DirectoryIndex off
           RewriteEngine Off
           AuthType openid-connect
           AllowOverride None
           Require valid-user
           LogLevel debug
            SSLOptions +StdEnvVars
            SSLOptions +ExportCertData
            SSLVerifyClient require
    </LocationMatch>