简体   繁体   English

如何从Java中的剩余请求中检索客户端证书

[英]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用于JavaJetty 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不可用,然后再尝试访问它们。

  • A few 3rd party security libraries have been known to alter these attribute in the past. 过去,已知一些第三方安全性库会更改这些属性。
  • Or you are not terminating the TLS/SSL connection at Jetty, such as at a firewall/router/load balancer (haproxy, nginx, apache httpd, or various hardware) (which means Jetty cannot see the certificate). 或者,您不是要在Jetty终止TLS / SSL连接,例如在防火墙/路由器/负载平衡器(haproxy,nginx,apache httpd或各种硬件)处终止(这意味着Jetty无法看到证书)。
  • You are not using a normal ServerConnector (such as UnixSocketConnector, LocalConnector, or a custom Connector) 您没有使用普通的ServerConnector(例如UnixSocketConnector,LocalConnector或自定义连接器)
  • Or you have a 3rd party security layer in your Java implementation. 或者,您在Java实现中具有第三方安全层。
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.

相关问题 如何使用 Quarkus 以两种方式 SSL 从 REST 服务中的请求中检索客户端证书 - How to retrieve the client certificate from a request in a REST service using Quarkus in two way SSL 从Rest Client请求通过服务到Web应用程序检索JSON - Retrieve JSON from Rest Client Request trough Service To Web Application JAVA 如何进行 PUT 请求 REST 客户端 - JAVA How to do PUT request REST Client 如何从Java REST服务中的POST请求有效负载中检索值? - How can I retrieve values from POST request payload in Java REST service? 从Java客户端应用程序的请求中检索从CookieStore中设置的cookie - Retrieve cookies from CookieStore set in request from java client application Java SSLServerSocket:请求客户端证书允许任何客户端证书 - Java SSLServerSocket: Request client certificate allowing ANY client certificate 如何使用 rest java 将 JSON 请求检索到方法中? - how to retrieve JSON request into method using rest java? 如何使用Java Rest客户端在POST负载中传递参数“ request”? - How to pass parameter 'request' in POST payload using Java Rest client? 如何使用证书发出REST Get请求? - How to make REST Get request using certificate? 我们是否真的需要Rest Java客户端,或者我们可以直接从HTML页面触发REST请求? - Do we really need a rest java client or we can directly fire rest request from HTML page
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM