Wildfly 的 JAXWS 实现似乎忽略了 bindingProvider 属性 com.sun.xml.ws.transport.https.client.SSLSocketFactory
Wildfly's JAXWS implementation seems to ignore bindingProvider property com.sun.xml.ws.transport.https.client.SSLSocketFactory
我的环境是 Maven 项目和 Wildfly (8.2.1) 作为应用程序服务器。我需要的是使用 SOAP 将传入的 REST 调用连接到第三方服务器。我需要 SSL 客户端身份验证;因此,我有自己的 KeyStore 和 TrustStore。因此我创建了我自己的 SSLContext 并且需要让 WebService 使用这个 SSLContext。
Wildfly 有问题,它使用了 JAXWS(Apache CXF?)的实现 - 我在这里描述了它(但用另一种方法来解决问题;因此 它不是重复的 post!):
其中一个主要问题似乎是 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 设置.
如果我们看看其他 posts(例如 How to programmatically set the SSLContext of a JAX-WS client?)这个 属性 应该 工作(根据那里的一些评论,即使对于 Wildfly ).但它不在我的情况下。这可能是什么原因造成的?
问题肯定是 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);
我希望这对遇到类似问题的人有所帮助...
我对 Widfly 8.2.1 的解决方案:
1) 添加文件 src/main/resources/META-INF/services/javax.xml.ws.spi.Provider,其中包含行 com.sun.xml.ws.spi.ProviderImpl inside
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);
在使用 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>
Apache CXF 忽略 JAX-WS 属性。您可以通过以下方式以编程方式指定 TLS 客户端参数:
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
tlsParams.setSSLSocketFactory(sslSocketFactory);
bindingProvider.getRequestContext().put(TLSClientParameters.class.getName(), tlsParams);
我的环境是 Maven 项目和 Wildfly (8.2.1) 作为应用程序服务器。我需要的是使用 SOAP 将传入的 REST 调用连接到第三方服务器。我需要 SSL 客户端身份验证;因此,我有自己的 KeyStore 和 TrustStore。因此我创建了我自己的 SSLContext 并且需要让 WebService 使用这个 SSLContext。
Wildfly 有问题,它使用了 JAXWS(Apache CXF?)的实现 - 我在这里描述了它(但用另一种方法来解决问题;因此 它不是重复的 post!):
其中一个主要问题似乎是 Wildfly 中使用的 JAXWS 似乎忽略了使用 属性 com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory
:
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 设置.
如果我们看看其他 posts(例如 How to programmatically set the SSLContext of a JAX-WS client?)这个 属性 应该 工作(根据那里的一些评论,即使对于 Wildfly ).但它不在我的情况下。这可能是什么原因造成的?
问题肯定是 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);
我希望这对遇到类似问题的人有所帮助...
我对 Widfly 8.2.1 的解决方案:
1) 添加文件 src/main/resources/META-INF/services/javax.xml.ws.spi.Provider,其中包含行 com.sun.xml.ws.spi.ProviderImpl inside
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);
在使用 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>
Apache CXF 忽略 JAX-WS 属性。您可以通过以下方式以编程方式指定 TLS 客户端参数:
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
tlsParams.setSSLSocketFactory(sslSocketFactory);
bindingProvider.getRequestContext().put(TLSClientParameters.class.getName(), tlsParams);