[英]How to retrieve client certificate from rest request in Java
I'm using Jersey
for REST
server in Java
and Jetty
as web server. 我正在将
Jersey
用于Java
和Jetty
REST
服务器用作Web服务器。 I have self signed
certificates. 我有
self signed
证书。 I want to fetch client certificate details from received HTTP Request. 我想从收到的HTTP请求中获取客户端证书详细信息。 How to obtain the information from
HttpServletRequest
? 如何从
HttpServletRequest
获取信息?
One method: 一种方法:
X509Certificate certs[] = (X509Certificate[])httpRequest.getAttribute("javax.servlet.request.X509Certificate");
Is this right? 这是正确的吗? This results in exception,
这导致异常,
Error [Ljava.lang.Object; cannot be cast to [Ljava.security.cert.X509Certificate
Should I include any additional JAR
? 我应该添加其他
JAR
吗? Or is there any way to obtain client certificate details? 还是有什么方法可以获取客户证书的详细信息?
I also came across, 我也遇到过
httpRequest.getHeader("ssl_client_cert");
Both ways not seems to work for me. 两种方式似乎都不适合我。 How to get the details?
如何获取详细信息?
First, ensure that your ServerConnector that handles SSL/TLS. 首先,确保您的ServerConnector处理SSL / TLS。 Next, that ServerConnector should have a SslConnectionFactory with a configured HttpConfiguration object within it.
接下来,该ServerConnector应该具有一个SslConnectionFactory,其中带有配置的HttpConfiguration对象。 That HttpConfiguration object should have the SecureRequestCustomizer added to it.
该HttpConfiguration对象应该添加了SecureRequestCustomizer。
In embedded-jetty parlance, it looks like this ... 用嵌入式码头的话来说,这看起来像是...
// SSL Context Factory
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("/path/to/keystore");
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setKeyManagerPassword("secret");
sslContextFactory.setTrustStorePath("/path/to/keystore");
sslContextFactory.setTrustStorePassword("password");
// SSL HTTP Configuration
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer()); // <-- THIS LINE
// SSL Connector
ServerConnector sslConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config));
sslConnector.setPort(8443);
server.addConnector(sslConnector);
If you are using a ${jetty.home}
and ${jetty.base}
split on standalone Jetty, then you'll want to check that the jetty-ssl.xml
is present in your configuration ... 如果您在独立的Jetty上使用
${jetty.home}
和${jetty.base}
拆分,则需要检查配置中是否存在jetty-ssl.xml
...
$ cd /path/to/my-jetty-base
$ java -jar /path/to/jetty-home/start.jar --list-config
Java Environment:
-----------------
java.home = /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/jre (null)
java.vm.vendor = Oracle Corporation (null)
java.vm.version = 25.202-b08 (null)
java.vm.name = Java HotSpot(TM) 64-Bit Server VM (null)
java.vm.info = mixed mode (null)
java.runtime.name = Java(TM) SE Runtime Environment (null)
java.runtime.version = 1.8.0_202-b08 (null)
java.io.tmpdir = /var/folders/w5/mmnzpk0n369dntp4nszlc8h40000gn/T/ (null)
user.dir = /path/to/my-jetty-base (null)
user.language = en (null)
user.country = US (null)
Jetty Environment:
-----------------
jetty.version = 9.4.15.v20190215
jetty.tag.version = master
jetty.home = /path/to/jetty-home
jetty.base = /path/to/my-jetty-base
...(snip lots of output)...
Jetty Active XMLs:
------------------
${jetty.home}/etc/jetty-threadpool.xml
${jetty.home}/etc/jetty.xml
${jetty.home}/etc/jetty-webapp.xml
${jetty.home}/etc/jetty-plus.xml
${jetty.home}/etc/jetty-annotations.xml
${jetty.home}/etc/jetty-deploy.xml
${jetty.home}/etc/jetty-http.xml
${jetty.home}/etc/jetty-ssl.xml <-- THIS LINE
${jetty.home}/etc/jetty-ssl-context.xml
${jetty.home}/etc/jetty-https.xml
${jetty.home}/etc/jetty-jaas.xml
${jetty.home}/etc/jetty-rewrite.xml
${jetty.base}/etc/demo-rewrite-rules.xml
${jetty.base}/etc/test-realm.xml
Once you have verified this base level configuration you are good to go with even using those attributes. 验证了此基本级别的配置后,即使使用这些属性,也可以使用。
Next, when you make a request to that secure connector, the various filters and servlets will have access to a number of request attributes that could prove useful to you. 接下来,当您向该安全连接器发出请求时,各种过滤器和Servlet将有权访问许多对您可能有用的请求属性。
These are the Servlet spec defined attributes that SecureRequestCustomizer
adds to your incoming HttpServletRequest. 这些是Servlet规范定义的属性,
SecureRequestCustomizer
将这些属性添加到传入的HttpServletRequest中。
javax.servlet.request.X509Certificate
holds an array of java.security.cert.X509Certificate
objects. javax.servlet.request.X509Certificate
包含一个java.security.cert.X509Certificate
对象数组。 javax.servlet.request.cipher_suite
holds your negotiated cipher suite as a String
object. javax.servlet.request.cipher_suite
将您协商的密码套件保存为String
对象。 javax.servlet.request.key_size
holds your keysize as an Integer
object. javax.servlet.request.key_size
将您的密钥大小保留为Integer
对象。 javax.servlet.request.ssl_session_id
holds your SSL Session ID as a String
object. javax.servlet.request.ssl_session_id
将您的SSL会话ID保留为String
对象。 These are the Jetty custom attributes that SecureRequestCustomizer
adds to your incoming HttpServletRequests. 这些是
SecureRequestCustomizer
添加到传入的HttpServletRequests中的Jetty定制属性。
org.eclipse.jetty.servlet.request.ssl_session
holds the active java.net.ssl.SSLSession
object for this connection. org.eclipse.jetty.servlet.request.ssl_session
拥有此连接的活动java.net.ssl.SSLSession
对象。 Since you are seeing a generic Object[]
from your attempt to use the attribute, perhaps you should debug and see what those objects actually are. 由于尝试使用该属性时看到的是通用
Object[]
,因此也许您应该调试并查看这些对象的实际含义。
Consider that something outside of Jetty's control might have replaced them, or made them unavailable to Jetty in the Servlet spec form before you attempted to access them. 考虑一下Jetty无法控制的某些内容可能已替换了它们,或者使它们在Servlet规范表单中对于Jetty不可用,然后再尝试访问它们。
Object certs[] = httpRequest.getAttribute("javax.servlet.request.X509Certificate");
for(Object cert: certs) {
System.out.printf("DEBUG: Cert[%s] = %s%n", cert.getClass().getName(), cert);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.