[英]In the Jetty server how can I obtain the client certificate used when client authentication is required?
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); 设置一个请求客户端身份验证的嵌入式Jetty服务器非常容易:只需要添加语句SslContextFactory.setNeedClientAuth(true); to the ssl context when configuring the server. 配置服务器时的ssl上下文。 Any client that has its certificate in the server's truststore will be able to establish a TLS connection to the server. 在服务器的信任库中拥有其证书的任何客户端都将能够与服务器建立TLS连接。
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? 有谁知道如何访问此证书或甚至可能?
Updated Aug 2019: for Jetty 9.4.20.v20190813 release. 2019年8月更新: Jetty 9.4.20.v20190813发布。
The certificates are added to the Request objects (such as HttpServletRequest ), by a HttpConfiguration Customizer . 证书通过HttpConfiguration Customizer添加到Request对象(例如HttpServletRequest )。
Specifically, the SecureRequestCustomizer . 具体来说, 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. 使用此SecureRequestCustomizer,您可以使用以下属性名称从HttpServletRequest.getAttribute(String)
调用访问有关SSL连接的各种部分。
javax.servlet.request.X509Certificate
an array of java.security.cert.X509Certificate
[] java.security.cert.X509Certificate
[]的数组
javax.servlet.request.cipher_suite
the String name of the cipher suite. 密码套件的String名称。 (same as what is returned from javax.net.ssl.SSLSession.getCipherSuite()
) (与从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 活动SSL会话ID的字符串表示形式(已经过化验)
There's a standard servlet request property: javax.servlet.request.X509Certificate 有一个标准的servlet请求属性:javax.servlet.request.X509Certificate
It returns an array of X509Certificates. 它返回一个X509Certificates数组。
We use this to get the name and look up the DN from the cert: 我们使用它来获取名称并从证书中查找DN:
x509Cert[0].getSubjectX500Principal().getName()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.