Wildfly的JAXWS实现似乎忽略了bindingProvider属性com.sun.xml.ws.transport.https.client.SSLSocketFactory

时间:2016-05-11 12:09:43

标签: java ssl soap jax-ws wildfly

我的环境是Maven Project和Wildfly(8.2.1)作为Application Server。我需要的是使用SOAP将传入的REST调用连接到第三方服务器。我需要SSL客户端身份验证;因此,我有自己的KeyStore和TrustStore。因此,我创建了自己的SSLContext,并且需要让WebService使用此SSLContext。

Wildfly存在问题,并且它使用了JAXWS(Apache CXF?)的实现 - 我在这里描述了它(但是用另一个方法来解决问题;因此它不是重复的帖子! ):
 Wildfly: How to use JAXWS-RI instead of Apache CXF (WebService client only)

其中一个主要问题似乎是Wildfly中使用的JAXWS似乎忽略了使用属性com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory设置自己的SSLContext:

MyWS_Service service = new MyWS_Service(null, new QName("http://...", "MyWS"));
MyWS port = service.getMyWSSOAP();

BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://hostname:443/.../...");

// the following setting is ignored!
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", mySslSocketFactory);

// in some posts, we see that we need to eliminate 'internal' in the property. This does not help!
bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", mySslSocketFactory);

如果我使用HttpsURLConnection.setDefaultSSLSocketFactory(mySslSocketFactory)来设置SSLContext,它确实有效 - 这意味着SSL连接已建立,这要归功于导入的根CA到SSLContext中自定义的TrustStore设置。< / p>

如果我们查看其他帖子(例如How to programmatically set the SSLContext of a JAX-WS client?),此属性应该有效(即使Wildfly根据其中的一些评论)。但它不适合我的情况。造成这种情况的原因是什么?

4 个答案:

答案 0 :(得分:7)

问题是Apache CXF忽略了

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

对某些地方的评论说。

所以我的最终解决方案是以编程方式设置所使用的HTTPConduit(而不是在cxf.xml文件中设置配置。)

// Set custom SSLContext.
HTTPConduit conduit = (HTTPConduit) ClientProxy.getClient(port).getConduit();
TLSClientParameters tlsClientParameters = new TLSClientParameters();
tlsClientParameters.setSSLSocketFactory(customSSLContext.getSocketFactory());
conduit.setTlsClientParameters(tlsClientParameters);

我希望这可以帮助有类似问题的人...

答案 1 :(得分:2)

使用Wildfly 10的HTTPConduit解决方案时,我必须添加jboss-deployment-structure.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
  <module name="org.jboss.ws.cxf.jbossws-cxf-client" services="import" />

  <module name="org.apache.cxf.impl" export="true">  
       <imports>  
            <include path="META-INF" />  
            <include path="META-INF/cxf" />  
            <include path="META-INF/services" />  
       </imports>         
  </module>   
        </dependencies>
    </deployment>

</jboss-deployment-structure>

答案 2 :(得分:1)

我对Widfly 8.2.1的解决方案:

1)在文件src / main / resources / META-INF / services / javax.xml.ws.spi.Provider中添加com.sun.xml.ws.spi.ProviderImpl行

2)添加maven依赖:

<dependency>
     <groupId>com.sun.xml.ws</groupId>
     <artifactId>jaxws-rt</artifactId>
     <version>2.2.8</version>
</dependency>

3)以这种方式添加SSLSocketFactory:

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

答案 3 :(得分:0)

Apache CXF忽略JAX-WS属性。您可以通过以下方式以编程方式指定TLS客户端参数:

TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
tlsParams.setSSLSocketFactory(sslSocketFactory);
bindingProvider.getRequestContext().put(TLSClientParameters.class.getName(), tlsParams);