我使用带有客户端身份验证的 tomcat http 连接器。如果客户端开始与我的服务器建立新连接并发送他的证书,我可以获取证书并在我的 Java 代码中从传入证书中读取公用名吗?如果是,如何?
谢谢 阿迪
最佳答案
您可以通过获取 HttpServletRequest
上的 javax.servlet.request.X509Certificate
属性来获取客户端证书链。这是 X509Certificate
s 的数组其中第一个(位置 0)是实际的客户端证书(如果需要中间 CA 证书,链的其余部分可能存在)。
X509Certificate certs[] =
(X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate");
// ... Test if non-null, non-empty.
X509Certificate clientCert = certs[0];
// Get the Subject DN's X500Principal
X500Principal subjectDN = clientCert.getSubjectX500Principal();
然后,您可以按照 this answer 中的描述在该主体(例如 CN)中获取各种 RDN(相对可分辨名称) :
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
String dn = subjectDN.getName();
LdapName ldapDN = new LdapName(dn);
for(Rdn rdn: ldapDN.getRdns()) {
System.out.println(rdn.getType() + " -> " + rdn.getValue());
}
(您也可以使用 BouncyCaSTLe 的 X509Name
来获取每个 RDN。)
在 X.509 证书中,主题 DN 是 RDN 的有序序列,每个 RDN 是一组 AVA(属性值断言),例如 CN=...
或 O=...
。原则上每个 RDN 可以有多个 AVA,这会导致这里出现问题,但这种情况很少见。您几乎可以假设每个 RDN 只有一个 AVA。 (可能对 this answer 感兴趣。)
关于java - 在 Tomcat 中读出传入的证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11945013/