In the Jetty server how can I obtain the client certificate used when client authentication is required?

≯℡__Kan透↙ 提交于 2019-12-03 07:58:34

问题


It is very easy to set up an embedded Jetty server that requests client authentication: One just needs to add the statement SslContextFactory.setNeedClientAuth(true); to the ssl context when configuring the server. Any client that has its certificate in the server's truststore will be able to establish a TLS connection to the server.

However I need to know which client of all the possible trusted clients is currently making a request; in other words I need to know the client certificate used in this connection, in particular in the handler. Does anyone know how to access this certificate or if it is even possible?


回答1:


Updated Aug 2019: for Jetty 9.4.20.v20190813 release.

The certificates are added to the Request objects (such as HttpServletRequest), by a HttpConfiguration Customizer.

Specifically, the SecureRequestCustomizer.

Your code to use this would be as follows (scroll down)...

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);

With this SecureRequestCustomizer in place you can access various pieces about the SSL connection from the HttpServletRequest.getAttribute(String) calls using the following attribute names.

javax.servlet.request.X509Certificate

an array of java.security.cert.X509Certificate[]

javax.servlet.request.cipher_suite

the String name of the cipher suite. (same as what is returned from javax.net.ssl.SSLSession.getCipherSuite())

javax.servlet.request.key_size

Integer of the key length in use

javax.servlet.request.ssl_session_id

String representation (hexified) of the active SSL Session ID




回答2:


There's a standard servlet request property: javax.servlet.request.X509Certificate

It returns an array of X509Certificates.

We use this to get the name and look up the DN from the cert:

x509Cert[0].getSubjectX500Principal().getName()


来源:https://stackoverflow.com/questions/20056304/in-the-jetty-server-how-can-i-obtain-the-client-certificate-used-when-client-aut

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!