You can get the client certificate chain by getting the javax.servlet.request.X509Certificate
attribute on your HttpServletRequest
. This is an array of X509Certificate
s where the first one (position 0) is the actual client certificate (the rest of the chain may be present if intermediate CA certificates are required).
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();
You can then get the various RDNs (relative distinguished name) in this principal (e.g. CN) as described in this answer:
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());
}
(You could also use BouncyCastle's X509Name
to get each RDN.)
In an X.509 certificate, the Subject DN is an ordered sequence of RDNs, each of which is a set of AVAs (Attribute Value Assertions), for example CN=...
or O=...
. In principle, there can be multiple AVAs per RDN, which would cause problems here, but this is very rare. You can almost assume that there is only one AVA per RDN. (Perhaps this answer might be of interest.)