【问题标题】:org.apache.cxf.binding.soap.SoapFault: Error during certificate path validation: Path does not chain with any of the trust anchorsorg.apache.cxf.binding.soap.SoapFault:证书路径验证期间出错:路径未与任何信任锚链接
【发布时间】:2025-11-22 13:25:02
【问题描述】:

我正在创建一个 Web 服务客户端以连接到服务。我按照以下步骤使用证书身份验证创建并连接到服务

  1. 执行wsdl URL后从浏览器下载证书并使用命令安装在cacerts中

    keytool -importcert -alias aliasname -file abc.cer -keystore cacerts -storepass storepwd
    

    使用以下命令从 jks 生成证书

    keytool -export -alias key -file xxxx.cer -keystore xxxx.jks 
    

    然后将上面生成的证书添加到trustore

    keytool -importcert -alias aliasname -file abc.cer -keystore cacerts -storepass storepwd
    
  2. 使用 cxf3.0.13、java 6、eclipse 生成的客户端代码

  3. 创建了以下安全属性

    org.apache.ws.security.crypto.provider=
    org.apache.ws.security.components.Merlin
    org.apache.ws.security.crypto.merlin.keystore.type=jks
    org.apache.ws.security.crypto.merlin.keystore.file=xxxx.jks
    org.apache.ws.security.crypto.merlin.keystore.password=key-pass
    org.apache.ws.security.crypto.merlin.truststore.file=cacerts
    org.apache.ws.security.crypto.merlin.truststore.password=cacertspwd
    
  4. 在 cxf 生成的客户端类中我添加了以下内容

    Service service = new Service(wsdlurl, service_name);
    ServicePort port = service.getServicePort();
    ((BindingProvider)port).getRequestContext().put("ws-security.signature.properties", "security.properties");
    ((BindingProvider)port).getRequestContext().put("ws-security.encryption.properties", "security.properties");
    ((BindingProvider)port).getRequestContext().put("ws-security.signature.username", "xxxxx");
    ((BindingProvider)port).getRequestContext().put("ws-security.encryption.username", "xxxxx");
    ((BindingProvider)port).getRequestContext().put("ws-security.callback-handler", "com.abc.ClientCallbackHandler");
    
    SearchResult result = port.search("abc");
    
  5. 创建了https://www.ibm.com/developerworks/library/j-jws13/index.html中指定的ClientCallbackHandler

    public class ClientCallbackHandler implements CallbackHandler {
        public void handle(Callback[] callbacks) throws IOException {
            for (int i = 0; i < callbacks.length; i++) {
                WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[i];
                String id = pwcb.getIdentifier();
                int usage = pwcb.getUsage();
                if (usage == WSPasswordCallback.DECRYPT
                        || usage == WSPasswordCallback.SIGNATURE) {
                    // used to retrieve password for private key
                    if ("clientkey".equals(id)) {
                        pwcb.setPassword("key-pass");
                    }
                }
            }
        }
    }
    

运行客户端类后,出现以下错误

org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://www.xxxxxxx.com}Service#{http://www.xxxxxxx.com}Search has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: Error during certificate path validation: Path does not chain with any of the trust anchors
        at org.apache.cxf.ws.security.wss4j.WSS4JUtils.createSoapFault(WSS4JUtils.java:275)
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:333)
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:190)
        at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:128)
        at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:112)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
        at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1682)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1559)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1356)
        at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
        at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:653)
        at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
        at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
        at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
        at $Proxy44.search(Unknown Source)
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during certificate path validation: Path does not chain with any of the trust anchors
Original Exception was java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
        at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:970)
        at org.apache.wss4j.dom.validate.SignatureTrustValidator.verifyTrustInCerts(SignatureTrustValidator.java:108)
        at org.apache.wss4j.dom.validate.SignatureTrustValidator.validate(SignatureTrustValidator.java:64)
        at org.apache.wss4j.dom.processor.SignatureProcessor.handleToken(SignatureProcessor.java:185)
        at org.apache.wss4j.dom.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:428)
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:278)
        ... 20 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
        at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(Unknown Source)
        at java.security.cert.CertPathValidator.validate(Unknown Source)
        at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:951)
        ... 25 more
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Error during certificate path validation: Path does not chain with any of the trust anchors
        at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:160)
        at $Proxy44.search(Unknown Source)
       Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during certificate path validation: Path does not chain with any of the trust anchors
Original Exception was java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
        at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:970)
        at org.apache.wss4j.dom.validate.SignatureTrustValidator.verifyTrustInCerts(SignatureTrustValidator.java:108)
        at org.apache.wss4j.dom.validate.SignatureTrustValidator.validate(SignatureTrustValidator.java:64)
        at org.apache.wss4j.dom.processor.SignatureProcessor.handleToken(SignatureProcessor.java:185)
        at org.apache.wss4j.dom.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:428)
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:278)
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:190)
        at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:128)
        at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:112)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
        at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1682)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1559)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1356)
        at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
        at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:653)
        at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
        at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
        at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
        ... 2 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
        at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(Unknown Source)
        at java.security.cert.CertPathValidator.validate(Unknown Source)
        at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:951)
        ... 25 more

我在这里做错了什么。谁能帮帮我

【问题讨论】:

    标签: java security ssl soap cxf


    【解决方案1】:

    wss4j 正在验证soap 签名证书,它不一定是您在下载WSDL 时使用的SSL 证书。

    您需要在信任库中导入服务器用来签署soap 消息的证书。选项

    1. 向您的服务提供商请求

    2. 记录一个 SOAP 响应并从 XML 签名的 X509Certificate 节点中提取它,

    .

    <KeyInfo>
      <X509Data>
         <X509Certificate>MIID5jCCA0+gA...lVN</X509Certificate>
      </X509Data>
    </KeyInfo>
    

    【讨论】:

    • 我在 sopa 响应中没有找到与 X509Certificate 节点相关的任何内容。我在
      下找到了 BinarySecurityToken。这就是你所指的。
    • 可能是,BinarySecurityToken 也可以包含证书,并且可以从ds:KeyInfo 引用,如here。 XML 签名太复杂了。查找以MII 开头并命名为“x509”的base64 字段,或post 和example。在任何情况下,服务提供商都应该向您发送认证链
    • 我从 SOAP 标头中提取了证书并验证了它已经存在于我的 JKS 文件中
    • 也许这是一个不必要的澄清,但您需要将证书添加到信任库“cacerts”而不是密钥库.jks
    • 也这样做了。但不工作。您能否让我知道有什么方法可以在收到响应后禁用服务器签名验证。当我添加 -Djavax.net.debug=all JVM 参数时,我能够看到加密和解密形式的响应。收到服务器签名验证后,它失败并出现上述异常。希望如果我禁用此验证将有助于进一步进行。
    最近更新 更多