使用 mod_jk 在 Apache 和 Tomcat 之间传递用户名和客户端证书

3
我希望能够通过SSL证书(用于自动化)或OpenID(用于人,我使用Auth0作为提供者)来验证Web服务。Web服务运行在Tomcat容器中,在Apache Web服务器后面使用JK。Web服务器已经使用Auth0(使用mod_auth_openidc)对其他路径进行了用户身份验证,并且仅可通过HTTPS访问。我还有一个数据库,目前将由Auth0提供的用户名映射到角色(用于Apache授权)。
我希望具备以下功能:
1.找出用户名
- 如果Apache已经登录用户,则使用该用户名 - 如果请求中使用了客户端证书,则将DN用作用户名 - 如果都没有,则重定向以使Apache进行身份验证
2.查找角色
- 基于用户名进行数据库查询
我已经发现可能需要编写过滤器,并且从jk代理文档中可以看出可以从请求中获取证书和用户名。我已编写了以下代码:
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配置才能使其正常工作。在Tomcat中,一个测试servlet位于/servlet/servlet。
我有以下Apache配置(为了简洁起见,某些部分被省略)。
DocumentRoot /var/www/repo

#correct OIDC configuration omitted

<VirtualHost myhost.mydomain.com:443>
    ServerName myhost.mydomain.com

DBDriver pgsql
#other DBD configurations are omitted

JkMount /servlet* worker1

<Directory /var/www/repo/servlet>
    DirectoryIndex off
    RewriteEngine Off
    AuthType openid-connect
    AllowOverride None
    AuthzDBDQuery "a correct database query"
    Require dbd-group allrepo
LogLevel debug
</Directory>

<Directory /var/www/repo>
    DirectoryIndex off
    RewriteEngine Off
    AllowOverride None
</Directory>

#correct letsencrypt configuration omitted
</VirtualHost>
1个回答

1
发现的原因是如果在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>

另一个可能的解决方案:

<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>

请查看https://tomcat.markmail.org/thread/iax6picwsjlhbohd以获取讨论内容


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接