【问题标题】:Wildfly's JAXWS implementation seems to ignore bindingProvider property com.sun.xml.ws.transport.https.client.SSLSocketFactoryWildfly 的 JAXWS 实现似乎忽略了 bindingProvider 属性 com.sun.xml.ws.transport.https.client.SSLSocketFactory
【发布时间】:2016-09-06 19:59:50
【问题描述】:

我的环境是一个 Maven 项目,Wildfly (8.2.1) 作为应用服务器。我需要的是使用 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 设置。

如果我们查看其他帖子(例如 How to programmatically set the SSLContext of a JAX-WS client?),这个属性应该工作(即使对于 Wildfly,根据那里的一些 cmets)。但它不适合我的情况。这可能是什么原因?

【问题讨论】:

  • 正如我对您之前帖子的评论中所述,我真的认为问题在于com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory 参考。你看到这条评论了吗? stackoverflow.com/a/19587610/152794
  • 是的,你是对的。因为 Wildfly 使用 CXF,所以它被明确地忽略了。我还找到了一个解决方案,我将在下周在这里发布。我不明白的是有人发布说它应该在 Wildfly 中使用这个属性集:stackoverflow.com/a/23053824/4106030

标签: java ssl soap jax-ws wildfly


【解决方案1】:

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

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

【讨论】:

    【解决方案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>
    

    【讨论】:

      【解决方案3】:

      我对 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);
      

      【讨论】:

        【解决方案4】:

        问题肯定是 Apache CXF 忽略了

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

        在某些 cmets 的对面。

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

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

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

        【讨论】:

        • 拜托,你是怎么做到的?如果我尝试使用 TLSClientParameters 类,则会收到错误“java.lang.NoClassDefFoundError: org/apache/cxf/configuration/jsse/TLSClientParameters”。我在我的 POM 上使用 jbossws-cxf-client 工件。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-28
        • 2012-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多