Authentication 使用x.509证书的Tomcat 9.x.x客户端身份验证
我正在使用Tomcat 9.0.19,并试图为特定的Web应用程序启用基于X.509证书的客户端身份验证,即I&A 总之,Tomcat适用于通过单向TLS启用基本I&A的应用程序。当访问具有基于证书的I&A的Web应用程序时,Tomcat似乎不会在发送服务器Hello Done之前请求客户端证书作为服务器Hello消息的一部分,随后它会失败身份验证检查: 2020年1月2日13:00:40.371 FINE[https-jsse-nio-443-exec-10]org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate查找证书 2020年1月2日13:00:40.830 FINE[https-jsse-nio-443-exec-10]org.apache.catalina.authenticator.SSLAuthenticator.doAuthentication此请求中未包含任何证书 在Wireshark中跟踪TLS流,并看到TLS 1.2握手。加密数据交换后不久,Tomcat发送一条“加密警报”消息,套接字关闭。正在尝试从浏览器中联系Tomcat,执行GET。浏览器不会提示我选择证书,这似乎也指向Tomcat没有从浏览器请求证书 任何帮助都将不胜感激 更多详情: 我们为Tomcat和客户机提供了一组证书,由中间CA颁发,由根CA签发。在客户机和服务器以及密钥存储中都设置了信任存储,其中包含正确的证书/密钥。Web应用程序设置为需要证书I&A Web.xml:Authentication 使用x.509证书的Tomcat 9.x.x客户端身份验证,authentication,ssl,tomcat,two-way,Authentication,Ssl,Tomcat,Two Way,我正在使用Tomcat 9.0.19,并试图为特定的Web应用程序启用基于X.509证书的客户端身份验证,即I&A 总之,Tomcat适用于通过单向TLS启用基本I&A的应用程序。当访问具有基于证书的I&A的Web应用程序时,Tomcat似乎不会在发送服务器Hello Done之前请求客户端证书作为服务器Hello消息的一部分,随后它会失败身份验证检查: 2020年1月2日13:00:40.371 FINE[https-jsse-nio-443-exec-10]org.apache.catali
<security-constraint>
<web-resource-collection>
<web-resource-name>All by default</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>OTService</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>
<realm-name>certificate</realm-name>
</login-config>
OTService角色在Tomcat-Users.xml中设置,并带有一个单用户帐户:
现在,server.xml中的连接器配置如下:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="100" SSLEnabled="true" scheme="https" secure="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="/apache-tomcat-9.0.19/conf/km/keyStore.jks"
certificateKeystorePassword="PASSWORD"
certificateKeyAlias="tomcat"
type="RSA" />
truststoreFile="/apache-tomcat-9.0.19/conf/km/trust_store.jks"
truststorePass="PASSWORD"
truststoreType="JKS"
certificateVerification="required"
clientAuth="true"
protocols="TLSv1.2"
</SSLHostConfig>
</Connector>
你知道为什么Tomcat不会请求客户端证书吗?我发现的第一个问题是Tomcat忽略了信任存储的Connector->SSLHostConfig设置,并使用了JRE默认信任存储。我发现它的方式是让浏览器将协商的TLS会话密钥保存到一个文件Google SSLKEYLOGFILE,然后配置Wireshark使用该文件,捕获浏览器Tomcat会话,然后能够以明文形式查看每条消息 接下来,我发现Tomcat实际上在请求客户端证书,但它发送的已接受根CA列表来自默认的JRE cacerts文件,而不是truststoreFile属性指定的文件。通过将setenv.sh文件添加到Tomcat bin目录,使用Java属性覆盖默认的信任存储位置,可以让Tomcat全面使用不同的文件 现在,我在做生意,浏览器能够完成TLS握手,但是认证和授权步骤失败了。我最终确定,在tomcat_users.xml文件中提供cert.subject字段的正确方法不是CN=OU Client,OU=Control Systems,O=IoTOY,L=Scottsdale,S=AZ,C=US,而是CN=OU Client,OU=Control Systems,O=IoTOY,L=Scottsdale,ST=AZ,C=US。最后,我有双向TLS工作 需要记住的一点是,如果Tomcat上运行的任何东西试图通过TLS连接到另一个使用商业CA证书的系统,它将失败,因为您现在使用的信任库没有商业根CA证书。一种补救方法是复制默认JRE cacerts文件,并将系统特定的CA证书添加到其中,然后从上面提到的setenv.sh文件指向该文件。如果您有:
<Connector ...>
<SSLHostConfig>
<Certificate A=1 B=2 C=3 />
D=4 E=5 F=6
</SSLHostConfig>
</Connector>
然后A、B、C是证书对象的属性,但D、E、F不是SSLHostConfig对象的属性——它们是不同的XML内容。需要将属性放入标记中:
<Connector ... >
<SSLHostConfig certificateVerification="required" truststoreFile=... >
<Certificate ...keystore... />
</SSLHostConfig>
</Connector>
在tomcat 9.0.14上进行测试时,我确实希望在初次握手时发出cert请求。我认为clientAuth没有真正的值。它是三值的。检查连接器文档。注意:CertificateRequest消息不是ServerHello消息的一部分。正确。它应该是必需的,或者可选的,或者没有。关于clientAuth值的观点很好。将其更改为required,没有任何区别。根据RFC 5246:如果适用于所选密码套件,非匿名服务器可以选择从客户端请求证书。此消息如果发送,将立即跟随ServerKeyExchange消息(如果发送);否则,此消息将跟随服务器的证书消息。我在Wireshark中看到的是,服务器Tomcat发送ServerHello消息,该消息包含:服务器Hello、证书链、服务器密钥交换、服务器Hello Done。因此,我希望在那一点上看到一个cert请求。来自服务器的下一条消息是Change Cipher Spec(更改密码规范)。因此,即使您使用默认的cacerts文件,您仍然获得了CertificateRequest。是的,但我的CA证书DNs列表中有一个错误,因此浏览器没有返回单个客户端/用户证书作为响应。