只对某些特定资源请求客户端证书认证

4
我正在Tomcat上部署Web应用程序,该应用程序最终应成为提供多种服务的平台。有时候,我需要能够使用客户端证书对用户进行身份验证,但仅在她访问某些servlet/url时才需验证证书并读取一些属性。
我得出结论,仅使用Tomcat和jsp/servlets是不可能使Web应用程序的一部分请求客户端证书身份验证的。要么整个Tomcat服务器每次到处都要求用户证书(clientAuth true或want),要么web.xml授权设置对于此场景无用。
是否有框架、应用服务器或某些特定的可靠架构可用于实现此要求?我想到了可能会有一个专门用于相互SSL认证的单独服务器实例,重定向用户并转发会话参数,但这种选择似乎管理起来相当复杂。我敢打赌有类似的解决方案,只是想知道是否有一些参考实现、指南等...谢谢。
2个回答

8

我曾经使用Tomcat直接完成这项任务,使用客户端证书重新协商。随着Tomcat新版本的推出,配置可能已经稍有变化,但基本思路如下:

  • Configure your connector for client authentication: set its trust store parameters, but use clientAuth="false". This is documented in the Tomcat documentation:

    Set to true if you want the SSL stack to require a valid certificate chain from the client before accepting a connection. Set to want if you want the SSL stack to request a client Certificate, but not fail if one isn't presented. A false value (which is the default) will not require a certificate chain unless the client requests a resource protected by a security constraint that uses CLIENT-CERT authentication.

  • In your web.xml file, use something like this:

    <web-app>
        <display-name>My Webapp</display-name>
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>App</web-resource-name>
                <url-pattern>/</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>cert</role-name>
            </auth-constraint>
            <user-data-constraint>
                <transport-guarantee>CONFIDENTIAL</transport-guarantee>
            </user-data-constraint>
        </security-constraint>
    
        <login-config>
            <auth-method>CLIENT-CERT</auth-method>
        </login-config>
    
        <security-role>
            <role-name>cert</role-name>
        </security-role>
    </web-app>
    

    Of course, adapt web-resource-collection with the URL pattern you need.


谢谢。好的,我尝试了类似的东西(实际上可能是同样的东西),但证书中的用户必须属于在Tomcat中预先定义的角色,因此它不是非常灵活/可扩展的。 - user8658912
1
你肯定会在后面需要一些角色,不是吗?如果你想允许任何被你的 CA 接受的证书,只需创建自己的领域,为进入的所有证书(并具有所需属性)分配一个共同的基本角色:http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html#Standard_Realm_Implementations - Bruno
'web-resource-name'元素中的“App”对应什么?它必须映射WAR(等)的名称吗,还是一个“任意”的标签? - monojohnny

1
您无法仅使用Tomcat完成此操作。客户端身份验证最多只能针对每个Web应用程序进行设置,或者您可以在server.xml的Connector元素中为整个容器设置它,不过这样做有什么用处呢?
如果您需要为每个资源设置它,则可以使用Apache HTTPD并使其终止SSL。 (它仍将通过头文件将客户端证书传递给Tomcat,以便Tomcat遵守Servlet规范,使其可用于Web应用程序。)然后,您可以配置关于SSL的几乎所有内容,甚至可以到达单个文件的级别。这还为您提供了各种其他好处,例如负载平衡。

您可以在连接器中使用 clientAuth="false",并在 web.xml 文件中添加 <auth-method>CLIENT-CERT</auth-method> 来实现此功能:这将使用重新协商。 - Bruno
我猜需要一些分布式架构。我看到过类似的平台,使用证书认证,传递一些jsessionid和一堆参数,并通过不同的URL进行重定向。我会看看Apache Httpd解决方案,谢谢。 - user8658912
@Bruno 是的,每个网络应用程序而不是每个资源。我已经调整了我的文本。 - user207421
我想移除客户端证书并使用应用程序在80端口上运行,而不是8443端口,即使用http而不是https。即使在连接器中进行更改后仍然无法正常工作。 - NoobCoder

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