如何以编程方式设置JAX-WS客户机的SSLContext? [英] How to programmatically set the SSLContext of a JAX-WS client?

查看:289
本文介绍了如何以编程方式设置JAX-WS客户机的SSLContext?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在分布式应用程序中的服务器上工作,该应用程序具有浏览器客户端,并且还与第三方参与服务器到服务器的通信。
我的服务器有一个CA签名的证书,让我的客户端使用TLS(SSL)通信使用HTTP / S和XMPP(安全)连接。这一切都很好。

I'm working on a server in a distributed application that has browser clients and also participates in server-to-server communication with a 3rd party. My server has a CA-signed certificate to let my clients connect using TLS (SSL) communication using HTTP/S and XMPP(secure). That's all working fine.

现在我需要使用JAX-WS通过HTTPS / SSL安全地连接到第三方服务器。在此通信中,我的服务器充当JAX-WS交互中的客户端,并且我有一个由第三方签名的客户端证书。

Now I need to securely connect to a 3rd party server using JAX-WS over HTTPS/SSL. In this communication, my server acts as client in the JAX-WS interation and I've a client certificate signed by the 3rd party.

我试图通过标准系统配置添加一个新的密钥库( -Djavax.net.ssl.keyStore = xyz )但我的其他组件明显受此影响。虽然我的其他组件使用专用参数用于其SSL配置( my.xmpp.keystore = xxx,my.xmpp.truststore = xxy,... ),他们最终使用全局 SSLContext 。 (配置命名空间 my.xmpp。似乎表示分离,但不是这样)

I tried adding a new keystore through the standard system configuration (-Djavax.net.ssl.keyStore=xyz) but my other components are clearly affected by this. Although my other components are using dedicated parameters for their SSL configuration (my.xmpp.keystore=xxx, my.xmpp.truststore=xxy, ...), it seems that they end up using the global SSLContext. (The configuration namespace my.xmpp. seemed to indicate separation, but it's not the case)

将我的客户端证书添加到我的原始密钥库中,但是 - 我的其他组件似乎不喜欢它。

I also tried adding my client certificate into my original keystore, but -again- my other components don't seem to like it either.

我认为我唯一的选择是编程钩入JAX-WS HTTPS配置以设置客户机JAX-WS交互的密钥库和信任库。

I think that my only option left is to programmatically hook into the JAX-WS HTTPS configuration to setup the keystore and truststore for the client JAX-WS interaction.

有关如何做的任何想法/指针?我发现的所有信息使用 javax.net.ssl.keyStore 方法或设置全局 SSLContext 猜测 - 将最终在同一confilc。最接近我得到的有用的东西是这个旧的错误报告,请求我需要的功能:添加支持将SSLContext传递给JAX-WS客户端运行时

Any ideas/pointers on how to do this? All information I find either uses the javax.net.ssl.keyStore method or is setting the global SSLContext that -I guess- will end up in the same confilc. The closest I got to something helpful was this old bug report that requests the feature I need: Add support for passing an SSLContext to the JAX-WS client runtime

任何需要?

推荐答案

这是一个难以破解的坚果,所以为了记录:

This one was a hard nut to crack, so for the record:

要解决这个问题,它需要一个自定义使用此自定义 KeyManager 访问分隔的<$ c $ c> KeyStore
我在这个优秀的博客条目中找到了 KeyStore SSLFactory 的基本代码:
动态动态-select-a-certificate-alias-when-invoking-web-services

To solve this, it required a custom KeyManager and a SSLSocketFactory that uses this custom KeyManager to access the separated KeyStore. I found the base code for this KeyStore and SSLFactory on this excellent blog entry: how-to-dynamically-select-a-certificate-alias-when-invoking-web-services

然后,专门的 SSLSocketFactory 需要插入到WebService上下文中:

Then, the specialized SSLSocketFactory needs to be inserted into the WebService context:

service = getWebServicePort(getWSDLLocation());
BindingProvider bindingProvider = (BindingProvider) service; 
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", getCustomSocketFactory()); 

getCustomSocketFactory() code> SSLSocketFactory 使用上述方法创建。这只适用于内置到JDK中的Sun-Oracle impl的JAX-WS RI,因为指示 SSLSocketFactory 属性的字符串是此实现的专有属性。

Where the getCustomSocketFactory() returns a SSLSocketFactory created using the method mentioned above. This would only work for JAX-WS RI from the Sun-Oracle impl built into the JDK, given that the string indicating the SSLSocketFactory property is proprietary for this implementation.

在这个阶段,JAX-WS服务通信是通过SSL保护的,但是如果您从同一个安全服务器()加载WSDL,引导问题,因为收集WSDL的HTTPS请求将不使用与Web服务相同的凭据。我通过使WSDL在本地可用(文件:/// ...)和动态更改Web服务端点来解决这个问题:(一个很好的讨论,为什么需要它可以找到此论坛

At this stage, the JAX-WS service communication is secured through SSL, but if you are loading the WSDL from the same secure server () then you'll have a bootstrap problem, as the HTTPS request to gather the WSDL will not be using the same credentials than the Web Service. I worked around this problem by making the WSDL locally available (file:///...) and dynamically changing the web service endpoint: (a good discussion on why this is needed can be found in this forum)

bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, webServiceLocation); 

现在WebService被引导,并且能够通过SSL与服务器对方使用命名)客户端证书和相互认证。 ∎

Now the WebService gets bootstrapped and is able to communicate through SSL with the server counterpart using a named (alias) Client-Certificate and mutual authentication. ∎

这篇关于如何以编程方式设置JAX-WS客户机的SSLContext?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆