java - getAttribute ("javax.servlet.request.X509Certificate") 未设置 (Spring,CXF,Jetty,JAX-RSv1.1)

标签 java ssl httpclient

我的客户端通过以下方式实现双向 SSL:


    private final static String KEYSTORE = "/security/client.jks";
    private final static String KEYSTORE_PASSWORD = "secret";
    private final static String KEYSTORE_TYPE = "JKS";
    private final static String TRUSTSTORE = "/security/certificates.jks";
    private final static String TRUSTSTORE_PASSWORD = "secret";
    private final static String TRUSTSTORE_TYPE = "JKS";
    ...
    KeyStore keystore = KeyStore.getInstance(KEYSTORE_TYPE);
    FileInputStream keystoreInput = new FileInputStream(new File(KEYSTORE));
    keystore.load(keystoreInput, KEYSTORE_PASSWORD.toCharArray());
    KeyStore truststore = KeyStore.getInstance(TRUSTSTORE_TYPE);
    FileInputStream truststoreIs = new FileInputStream(new File(TRUSTSTORE));
    truststore.load(truststoreIs, TRUSTSTORE_PASSWORD.toCharArray());
    SSLSocketFactory socketFactory = new SSLSocketFactory(keystore, KEYSTORE_PASSWORD, truststore);
    Scheme scheme = new Scheme("https", 8543, socketFactory);
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(scheme);
    ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);
    httpclient = new DefaultHttpClient(ccm);
    HttpResponse response = null;
    HttpGet httpget = new HttpGet("https://mylocalhost.com:8543/test");
    response = httpclient.execute(httpget);
    ...

我尝试通过 javax.servlet.http.HttpServletRequest.getAttribute("javax.servlet.request.X509Certificate") 从客户端检索服务器端的 X.509 证书,如下所述:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletRequest.html#getAttribute%28java.lang.String%29 .

我通过以下方式在服务器端获取 HttpServletRequest:
HttpServletRequest servletRequest = (HttpServletRequest) msg​​.get("HTTP.REQUEST");通过扩展 AbstractPhaseInterceptor 的拦截器类的 handleMessage(Message msg) 方法。由于不允许更改某些 Maven 依赖项,我必须在服务器端使用 JAX-RS 1.1.1,因此我无法使用 ContainerRequestFilter(从 JAX-RS 2.0 开始支持)。

我的问题是服务器端的 getAttribute("javax.servlet.request.X509Certificate") 始终返回 null。如果我验证服务器和客户端之间的流量,我可以看到来自服务器的证书已发送到客户端,握手有效。但我看不到客户端证书已发送到服务器,我认为这是 getAttribute("javax.servlet.request.X509Certificate") 返回 null 的原因。有人知道我该如何解决这个问题吗?我已经在客户端尝试了一些其他实现,但没有任何改变。

我做错了什么?非常感谢!

附加信息:我在服务器端看到设置了 javax.servlet.request.ssl_session_id、javax.servlet.request.key_size 和 javax.servlet.request.cipher_suite,但是 key javax.servlet.request.X509Certificate未设置。我正在使用 Jetty Server 8.1.15、Apache CXF 2.7.x 和 JAX-RS 1.1.1。我尝试通过 http://cxf.apache.org/docs/jetty-configuration.html 配置 Jetty和 http://cxf.apache.org/docs/secure-jax-rs-services.html#SecureJAX-RSServices-Configuringendpoints ,该属性仍未设置。

最佳答案

问题解决了。这不是代码中的问题,只是证书问题。我的问题是我也是 X509 证书的初学者,这是服务器和客户端之间的握手问题。在这种情况下,只有 SSL/握手调试帮助了我。调试日志告诉服务器只接受来自特定 CA 的客户端证书,服务器在 ServerHello 消息期间的证书请求中告诉客户端所需的 CA。由于客户端没有来自该 CA 的证书,它没有发送任何东西,客户端和服务器之间的连接随后关闭,结果是 javax.servlet.request.X509Certificate 没有设置。

对于所有其他有时可能遇到相同问题的人(这似乎是关于 IBM 的常见 SSL 配置问题,如下面第一个链接中提到的),以下资源对我帮助很大:
- http://www-01.ibm.com/support/docview.wss?uid=swg27038122&aid=1 (第 16 和 17 页)
- http://java.dzone.com/articles/how-analyze-java-ssl-errors (显示为握手应有的样子)
- need help Debugging SSL handshake in tomcat (显示如何在 Java 中调试 ssl 错误)
- https://thomas-leister.de/internet/eigene-openssl-certificate-authority-ca-erstellen-und-zertifikate-signieren/ (德语,但也许你可以找到对应的英语)
- https://access.redhat.com/site/documentation/en-US/Red_Hat_JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/i382674.html (德文续)
- http://www.webfarmr.eu/2010/04/import-pkcs12-private-keys-into-jks-keystores-using-java-keytool/ (如何创建keystore和truststore)

创建自己的 CA、服务器和客户端证书并为两者创建 keystore 和信任库后,现在设置属性:
- Here15_1: javax.servlet.request.X509Certificate
- Here16_2: 类 [Ljava.security.cert.X509Certificate;
- Here16_3: [Ljava.security.cert.X509Certificate;@43b8f002
服务器代码现在也能够提取客户端证书信息。

关于java - getAttribute ("javax.servlet.request.X509Certificate") 未设置 (Spring,CXF,Jetty,JAX-RSv1.1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24351472/

相关文章:

c++ - OpenSSL AES 仅适用于某些机器,即使使用静态链接也是如此

android - 我在获取响应时处理我的 Web 服务 - 如何从服务器端获取响应?

java - 在android中取消Http连接

java - 作为名称或标识符的保留字

java - 未找到 Android 源?

java - 什么是更好的?两个 Hashmap 还是一个使用一个类?

java - 在vlcj MediaPlayer上添加透明JLabel?

google-chrome - 如何从 Electron 应用程序调试 'unable to verify the first certificate'?

asp.net - 在 azure 上的 asp.net vnext 网站上禁用端口 80

java - Apache HttpClient 异常 PKIX 路径构建失败