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

CXF:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我构建了一个 CXF 客户端来调用 SOAP Web 服务。我将服务器的证书导入到我的 cacerts 信任库中(我知道 CXF 默认使用 cacerts)并且我使用以下代码来实现调用。但是,生成以下错误:

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

QName serviceQName = new QName("Namespace", "ServiceName");
String urlString = "https:endpoint?wsdl";
QName portQName = new QName("Namespace", "PortName");

service = Service.create(serviceQName);
service.addPort(portQName, SOAPBinding.SOAP11HTTP_BINDING, urlString);
Dispatch<Source> sourceDispatch = service.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD);
BindingProvider bindingProvider = sourceDispatch;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, urlString);
Source result = sourceDispatch.invoke(new StreamSource(exchange.getIn().getBody(InputStream.class)));

您需要将证书导入密钥库。这个答案是一个常见的解决方案。

"PKIX path building failed" and "unable to find valid certification path to requested target"

同时尝试将密钥库和信任库路径和密码添加到 VM 选项。

-Djavax.net.ssl.keyStore=C:\...\keystore.jks
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=C:\..\truststore.jks
-Djavax.net.ssl.trustStorePassword=password
-Djavax.net.ssl.type=JKS

错误实际上是 CXF 错误,而不是证书错误。具体来说,Binding Provider 实际上忽略了 JAXWS 属性,我必须传递 SSL 上下文,如下所示:

SSLContext sc = "your custom SSL Context"
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
tlsParams.setSSLSocketFactory(sc.getSocketFactory());