web-dev-qa-db-ja.com

Jettyサーバーで、クライアント認証が必要なときに使用されるクライアント証明書を取得するにはどうすればよいですか?

クライアント認証を要求する組み込みJettyサーバーをセットアップするのは非常に簡単です。ステートメントSslContextFactory.setNeedClientAuth(true);を追加するだけです。サーバーを構成するときにsslコンテキストに。サーバーのトラストストアに証明書があるすべてのクライアントは、サーバーへのTLS接続を確立できます。

ただし、信頼できるすべてのクライアントのうち、現在リクエストを行っているクライアントを知る必要があります。言い換えれば、この接続、特にハンドラーで使用されるクライアント証明書を知る必要があります。誰かがこの証明書にアクセスする方法を知っていますか、それが可能かどうかさえ知っていますか?

18
Brian Reinhold

2019年8月に更新:Jetty9.4.20.v20190813リリース用。

証明書は、 HttpConfigurationCustomizer によって、 Request オブジェクト( HttpServletRequest など)に追加されます。

具体的には、 SecureRequestCustomizer です。

これを使用するためのコードは次のようになります(下にスクロール)...

_Server server = new Server();

// === HTTP Configuration ===
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(8443);
http_config.setOutputBufferSize(32768);
http_config.setRequestHeaderSize(8192);
http_config.setResponseHeaderSize(8192);
http_config.setSendServerVersion(true);
http_config.setSendDateHeader(false);

// === Add HTTP Connector ===
ServerConnector http = new ServerConnector(server,
    new HttpConnectionFactory(http_config));
http.setPort(8080);
http.setIdleTimeout(30000);
server.addConnector(http);

// === Configure SSL KeyStore, TrustStore, and Ciphers ===
SslContextFactory sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath("/path/to/keystore");
sslContextFactory.setKeyStorePassword("changeme");
sslContextFactory.setKeyManagerPassword("changeme");
sslContextFactory.setTrustStorePath("/path/to/truststore");
sslContextFactory.setTrustStorePassword("changeme");
// OPTIONAL - for client certificate auth (both are not needed)
// sslContextFactory.getWantClientAuth(true)
// sslContextFactory.setNeedClientAuth(true)

// === SSL HTTP Configuration ===
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer()); // <-- HERE

// == Add SSL Connector ===
ServerConnector sslConnector = new ServerConnector(server,
    new SslConnectionFactory(sslContextFactory,"http/1.1"),
    new HttpConnectionFactory(https_config));
sslConnector.setPort(8443);
server.addConnector(sslConnector);
_

このSecureRequestCustomizerを配置すると、次の属性名を使用して、HttpServletRequest.getAttribute(String)呼び出しからSSL接続に関するさまざまな部分にアクセスできます。

_javax.servlet.request.X509Certificate_

_Java.security.cert.X509Certificate_ []の配列

_javax.servlet.request.cipher_suite_

暗号スイートの文字列名。 ( javax.net.ssl.SSLSession.getCipherSuite() から返されるものと同じ)

_javax.servlet.request.key_size_

使用中のキーの長さの整数

_javax.servlet.request.ssl_session_id_

アクティブなSSLセッションIDの文字列表現(16進)

16
Joakim Erdfelt

標準のサーブレットリクエストプロパティがあります:javax.servlet.request.X509Certificate

X509Certificatesの配列を返します。

これを使用して名前を取得し、証明書からDNを検索します。

x509Cert[0].getSubjectX500Principal().getName()
8
Will Hartung