在 SAAJ Soap Connection 中禁用证书检查

Disable certificate check in SAAJ Soap Connection

Java EE 应用程序,其中存在使用 SoapClient 对象的 SOAP 调用 (部署在 Wildfly 9 中):

SOAPMessage reply = con.call(message, url);

我收到以下消息:

原因:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

在 sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) 在 org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:183)

由于证书问题,尝试绕过错误:

    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }
            }
    };     
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());


    soapConnectionFactory = SOAPConnectionFactory.newInstance();

这没有任何效果

有什么想法吗?

如果 CXF 是您的客户端框架,那么它不会使用默认的 HTTP 套接字工厂,而是使用它自己的工厂。

因此,我建议您使用 CXF manual and the TLS parameters configuration

中描述的 CXF 配置工具

它归结为为您的特定端点创建管道并设置其参数,例如为 HelloWorld 命名空间上的端点设置配置:

<http:conduit name="{http://apache.org/hello_world}HelloWorld.http-conduit">
<http:tlsClientParameters>
  <sec:trustManagers>
    <sec:keyStore type="JKS" password="password"
                  file="my/file/dir/Truststore.jks"/>
  </sec:trustManagers>
</http:tlsClientParameters>

请注意,您可以设置 SSLSocketFactory 而不是密钥库(参见上面的第二个 link):

Client TLS Parameters : sslSocketFactory > A SSLSocketFactory to use. All other bean properties are ignored if this is set.

如果您不想使用 XML / Spring 配置,您可以通过 taping into the CXF API 求助于编程调用:

How to configure the HTTPConduit for the SOAP Client?
First you need get the HTTPConduit from the Proxy object or Client, then you can set the HTTPClientPolicy, AuthorizationPolicy, ProxyAuthorizationPolicy, TLSClientParameters, and/or HttpBasicAuthSupplier.

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
...

URL wsdl = getClass().getResource("wsdl/greeting.wsdl");
SOAPService service = new SOAPService(wsdl, serviceName);
Greeter greeter = service.getPort(portName, Greeter.class);

// Okay, are you sick of configuration files 
 // This will show you how to configure the http conduit dynamically
Client client = ClientProxy.getClient(greeter);
HTTPConduit http = (HTTPConduit) client.getConduit();

HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();

httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setReceiveTimeout(32000);

http.setClient(httpClientPolicy);

...
  greeter.sayHi("Hello");

您还可以查看此 SO 答案 How to programmatically set the SSLContext of a JAX-WS client?,其中包含针对 CXF 和非 CXF 案例的解决方案。

您可能需要特别查看 this solution

<http-conf:conduit name="*.http-conduit">
  <http-conf:tlsClientParameters useHttpsURLConnectionDefaultSslSocketFactory="true" />
<http-conf:conduit>