在 Google/StackOverflow 上搜索了几个小时后,我得出结论,没有人对此有一个可靠的、自上而下的答案,所以我将尝试再次询问。
我需要一个特定的 Web 应用程序来强制使用客户端证书(我的意思是强制)。 我的 tomcat 连接器描述为(注意 Apr 配置变量的使用):
<Connector port="443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
SSLEngine="on"
SSLCertificateFile="conf/server.crt"
SSLCertificateKeyFile="conf/server.key"
SSLPassword="password"
SSLCACertificateFile="conf/ca.crt"
SSLVerifyClient="none"
/>
我用这个 web.xml 制作了一个简单的 Web 应用程序,其中包含一个页面:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="...">
<display-name>Security</display-name>
<security-constraint>
<display-name>ClientCertificateRequired</display-name>
<web-resource-collection>
<web-resource-name>any</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<description/>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
</web-app>
到目前为止,一切都很好。如果我使用网络浏览器请求该页面,系统会要求我选择一个证书。这一切看起来都不错。
当我点击取消时,我意识到我遇到了问题!页面就简单地显示出来了。这不是我所期望的。
经过更多测试,我开始意识到 tomcat 可能会尝试以用户身份验证证书(当我添加角色要求时它会尝试这样做)。这是不可用的,因为无法在 tomcat-users.xml 中动态注册大量的客户端证书。
任何人都可以解释一下我在这里做错了什么吗?
我希望此 Web 上下文在显示任何内容之前强制要求客户端证书,同时允许其他上下文排除该要求。最好不要求助于自定义 servlet 来执行额外的服务器端验证。
致以最诚挚的问候, 罗里
在 server.xml Connector 部分,尝试将 SSLVerifyClient 设置为
optional
(如 Java 中的 WantClientAuth)或 require
(needClientAuth)。此 SSL 开关由 tcnative (openssl) 控制,但不是 tomcat (catalina) 本身。
参见:http://www.modssl.org/docs/2.1/ssl_reference.html#ToC13
顺便说一句,通过 Http11NioProtocol 启用 SSL(tomcat 使用 JSSE 实现)也是不错的选择。
您需要做的就是将连接器的 SSLVerifyClient 属性更改为 required
(注意,SSLVerifyClient是certificateVerification的别名,您可以查看Apache Tomcat文档。这里)
您的连接器必须看起来像
<Connector port="443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
SSLEngine="on"
SSLCertificateFile="conf/server.crt"
SSLCertificateKeyFile="conf/server.key"
SSLPassword="password"
SSLCACertificateFile="conf/ca.crt"
SSLVerifyClient="required"
/>