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

bad*_*era 4 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:如何使用JAXWS-RI而不是Apache CXF(仅限WebService客户端)

其中一个主要问题似乎是Wildfly中使用的JAXWS似乎忽略了使用属性设置自己的SSLContext 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);
Run Code Online (Sandbox Code Playgroud)

它被忽略的证据是,如果我HttpsURLConnection.setDefaultSSLSocketFactory(mySslSocketFactory)用来设置SSLContext,它确实有效 - 意味着SSL连接已建立,这要归功于导入的根CA到SSLContext中自定义的TrustStore设置.

如果我们查看其他帖子(例如,如何以编程方式设置JAX-WS客户端的SSLContext?),这个属性应该可以工作(即使对Wildfly也有一些评论).但它不适合我的情况.这可能是什么原因?

bad*_*era 8

问题是Apache CXF忽略了这个问题

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

在某些评论的相反位置.

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

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

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


小智 6

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

TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
tlsParams.setSSLSocketFactory(sslSocketFactory);
bindingProvider.getRequestContext().put(TLSClientParameters.class.getName(), tlsParams);
Run Code Online (Sandbox Code Playgroud)