クライアント認証でTomcat httpコネクタを使用しています。クライアントがサーバーへの新しい接続を開始して証明書を送信した場合、証明書を取得して、Java コードで受信証明書から共通名を読み取ることができますか? はいの場合、どのように?
ありがとうアディ
クライアント認証でTomcat httpコネクタを使用しています。クライアントがサーバーへの新しい接続を開始して証明書を送信した場合、証明書を取得して、Java コードで受信証明書から共通名を読み取ることができますか? はいの場合、どのように?
ありがとうアディ
javax.servlet.request.X509Certificate
の属性を取得することで、クライアント証明書チェーンを取得できますHttpServletRequest
。X509Certificate
これはの配列で、最初のもの (位置 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();
次に、この回答で説明されているように、このプリンシパル (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 の順序付けられたシーケンスであり、それぞれが AVA (属性値アサーション) のセットです (例:CN=...
やO=...
. 原則として、RDN ごとに複数の AVA が存在する可能性があるため、ここで問題が発生しますが、これは非常にまれです。RDN ごとに 1 つの AVA しかないとほぼ想定できます。(おそらく、この答えは興味深いかもしれません。)
mazaneicha のクレジット:
String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
if (cipherSuite != null) {
X509Certificate certChain[] = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
if (certChain != null) {
for (int i = 0; i < certChaNin.length; i++) {
System.out.println ("Client Certificate [" + i + "] = "
+ certChain[i].toString());
}
}
}