当前位置: 首页 > 知识库问答 >
问题:

如何以编程方式设置JAX-WS客户端的SSLContext?

夏侯昆琦
2023-03-14

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

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

我试图通过标准系统配置添加一个新的密钥库(-Djavax.net.ssl.keystore=xyz),但我的其他组件显然受到了影响。尽管我的其他组件使用专用参数进行SSL配置(my.xmpp.keystore=xxx,my.xmpp.truststore=xxy,),但它们似乎最终使用了全局SSLContext。(配置名称空间my.xmpp.似乎表示分离,但事实并非如此)

我还尝试将客户机证书添加到原始密钥库中,但我的其他组件似乎也不喜欢它。

我认为我剩下的唯一选择是以编程方式连接到JAX-WS HTTPS配置中,为客户端JAX-WS交互设置密钥库和信任库。

有关于如何做到这一点的想法/建议吗?我找到的所有信息要么使用javax。网ssl。keyStore方法,或者正在设置全局SSLContext,我猜,它最终将在同一个confilc中结束。我得到的最有帮助的东西是这个旧的bug报告,它请求我需要的特性:添加对向JAX-WS客户端运行时传递SSLContext的支持

有人拍吗?

共有3个答案

司空修贤
2023-03-14

我尝试了以下方法,但在我的环境中无效:

bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", getCustomSocketFactory());

但不同的房产却很有魅力:

bindingProvider.getRequestContext().put(JAXWSProperties.SSL_SOCKET_FACTORY, getCustomSocketFactory());

代码的其余部分取自第一个回复。

阎啸
2023-03-14

这就是我在这篇文章的基础上通过一些小的调整解决它的方法。此解决方案不需要创建任何其他类。

SSLContext sc = SSLContext.getInstance("SSLv3");

KeyManagerFactory kmf =
    KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );

KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
ks.load(new FileInputStream( certPath ), certPasswd.toCharArray() );

kmf.init( ks, certPasswd.toCharArray() );

sc.init( kmf.getKeyManagers(), null, null );

((BindingProvider) webservicePort).getRequestContext()
    .put(
        "com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory",
        sc.getSocketFactory() );
秦鸿羽
2023-03-14

这个问题很难解决,所以郑重声明:

为了解决这个问题,它需要一个自定义的KeyManager和一个SSLSocketFactory来使用这个自定义KeyManager访问分开的密钥库。我在这篇优秀的博文中找到了这个密钥库和SSLFactory的基本代码:how-to-dynamic-select-a-certificate-alias-when-invoking-web-services

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

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

其中getCustomSocketFactory()返回使用上述方法创建的SSLSocketFactory。考虑到表示SSLSocketFactory属性的字符串是该实现的专有属性,这只适用于JDK中内置的Sun Oracle impl中的JAX-WS RI。

在这个阶段,JAX-WS服务通信是通过SSL进行安全保护的,但是如果您从同一个安全服务器()加载WSDL,那么您将遇到引导问题,因为收集WSDL的HTTPS请求将不会使用与Web服务相同的凭据。我通过使WSDL在本地可用来解决这个问题(file:///...)以及动态更改web服务endpoint:(关于为什么需要这样做的详细讨论可以在这个论坛上找到)

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

现在,WebService已启动,并且能够使用命名(别名)客户端证书和相互身份验证通过SSL与服务器对等方通信。∎

 类似资料:
  • 问题内容: 我正在使用具有浏览器客户端的分布式应用程序中的服务器,并且还参与了与第三方的服务器到服务器通信。我的服务器具有CA签名的证书,可让我的客户端使用HTTP / S和XMPP(安全)通过TLS(SSL)通信进行连接。一切都很好。 现在,我需要通过HTTPS / SSL使用JAX-WS安全地连接到第三方服务器。在此通信中,我的服务器在JAX-WS交互中充当客户端,并且我有一个由第三方签名的客

  • 问题内容: 我已经使用JAXWS-RI 2.1为基于WSDL的Web服务创建了一个接口。我可以与Web服务进行交互,没有问题,但是无法指定将请求发送到Web服务的超时时间。如果由于某种原因它没有响应,则客户似乎永远旋转它的轮子。 到处搜寻表明我可能应该尝试执行以下操作: 我还发现,根据您拥有的JAXWS-RI版本,您可能需要设置以下属性: 我的问题是,无论以上哪一项是正确的,我都不知道 在哪里 可

  • 问题内容: 我尝试使用JAX-WS检索客户端IP,我曾经使用过: 我在要求中得到一个,mc不为空。 我的问题是,因为我使用的是Java独立应用程序,所以要使用哪个JAR ? 谢谢 问题答案: 如何获取jax-ws服务的Web服务客户端地址取决于您是否: 将Web服务作为servlet运行(在Java EE容器中),或者 将Web服务作为独立应用程序运行(Java SE 6或7)。 Servlet

  • 问题内容: 我的问题很简单 如何以编程方式设置我的按钮layout_gravity? 我在互联网上找到了它,但它只是抛出了一个Nullpointer异常: 有什么办法吗? 问题答案: Java Kotlin 有关重力值以及如何设置重力,请检查“重力”。 基本上,您应该选择依赖于父项。可以是等等。

  • 问题内容: 我有一个奇怪的问题。我试图以编程方式将dataSource分配给表。 我已使用界面生成器在ViewController中为其创建了一个和IBOutlet。我创建了一个实现的类。我将表的设置为dataSource的实例。一切都会编译并正常运行,直到设置dataSource的行在运行时执行。 错误是并且定义线突出显示。 有什么想法为什么我得到这个运行时错误?我正在Swift中使用XCode

  • 问题内容: 这个问题类似于: jsf:在UI中绑定到inputtext的integer属性在提交时设置为零 但是我对解决方案并不完全满意。上下文是相同的:我有一个Web表单,需要一个Integer值。如果文本框为空,我希望我的Integer字段为“null”,但是EL Parser会自动将我的id字段设置为“ 0”。 我可以通过在本地Tomcat VM中设置JVM参数来解决此问题: -Dorg.a