CXF客户端:无法找到请求目标的有效认证路径

3

我正在尝试实现一个基于CXF的Web服务客户端,这个Web服务也是由我编写的。

我的Web服务很好用(通过soapUI测试正常),但运行客户端时会出现以下错误:

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)

这条消息明显指向了一个证书问题,所以我进行了快速搜索,并找到了正确的方法来 支持CXF中的SSL,并在我的Spring应用程序上下文配置XML文件中添加了以下内容:

  <http:conduit name="https://myserver/myws/register/soap?wsdl:{http://glob.reg.com/myws}.http-conduit">

    <http:tlsClientParameters>
      <sec:keyManagers keyPassword="password">
        <sec:keyStore type="JKS" password="password"
                      file="my/file/dir/Morpit.jks"/>
      </sec:keyManagers>
      <sec:trustManagers>
        <sec:keyStore type="JKS" password="password"
                      file="my/file/dir/Truststore.jks"/>
      </sec:trustManagers>
      <sec:cipherSuitesFilter>
        <!-- these filters ensure that a ciphersuite with
             export-suitable or null encryption is used,
             but exclude anonymous Diffie-Hellman key change as
             this is vulnerable to man-in-the-middle attacks -->
        <sec:include>.*_EXPORT_.*</sec:include>
        <sec:include>.*_EXPORT1024_.*</sec:include>
        <sec:include>.*_WITH_DES_.*</sec:include>
        <sec:include>.*_WITH_AES_.*</sec:include>
        <sec:include>.*_WITH_NULL_.*</sec:include>
        <sec:exclude>.*_DH_anon_.*</sec:exclude>
      </sec:cipherSuitesFilter>
    </http:tlsClientParameters>
    <http:authorization>
      <sec:UserName>Betty</sec:UserName>
      <sec:Password>password</sec:Password>
    </http:authorization>
    <http:client AutoRedirect="true" Connection="Keep-Alive"/>

  </http:conduit>

重新构建了客户端。客户端已经成功构建,但我仍然得到完全相同的错误和完全相同的堆栈跟踪,就好像我从未添加过这个“http:conduit”一样。
我还没有将证书添加到存储中,存储路径不正确,但这是故意的,因为我只想看看重新构建的客户端如何报告此问题,并调整到新的“http:conduit”信息。
相反,我惊讶地发现它完全被忽略了。
我错过了什么?
正确的方法是什么?
更新:我刚注意到我的applicationcontext.xml用这个错误消息强调了“http:conduit”。
The prefix "http" for element "http:conduit" is not bound.

所以我进行了快速搜索,并找到了一个建议的线程,链接如下:a thread

客户端需要使用包含 STS 证书的密钥库来配置 HTTP 传输通道,例如:

 <http:conduit name="https://localhost:.*">
      <http:tlsClientParameters disableCNCheck="true">
        <sec:trustManagers>
          <sec:keyStore type="jks" password="cspass" resource="clientstore.jks"/>
        </sec:trustManagers>
      </http:tlsClientParameters>
  </http:conduit>

这进一步加强了@GreyBeardedGeek所写的内容。现在要去处理这个问题...


1
你所忽略的是,你需要指向一个有效的信任存储库,并且其中包含与服务器证书匹配的有效证书。 - GreyBeardedGeek
@GreyBeardedGeek 谢谢。你的意思是说,除非我提供有效的信任存储并具有与服务器证书匹配的有效证书,否则生成/编译的代码将把我的pom.xml中的<http:conduit部分视为从未放置在那里? - Withheld
1
不,我的意思是你的通道指定了一个信任存储库,因此该信任存储库必须包含服务器的证书,并具有到受信任证书的有效证书链,否则你将会得到你目前遇到的错误。 - GreyBeardedGeek
@GreyBeardedGeek 我现在要尝试你的建议(请参见上面的更新)。我只是业余时间做这个项目,所以在能够采取新的见解之前需要一些时间。非常感谢你迄今为止的帮助。 - Withheld
@GreyBeardedGeek 好的,我终于从头开始构建了一个完整的信任存储库,包含整个证书链并包含在客户端的JAR中,但这并没有帮助解决问题,仍然出现完全相同的错误。我有一种感觉那是错误的方向。现在的问题是我该如何继续? - Withheld
1个回答

3

问题已解决!

我仔细遵循了这篇 magicmonster 文章(请注意“旧版本的 Java”和默认密码“changeit”),将整个自签名证书链导入到 Java 的受信任证书列表中:

http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html

但还有一个非常重要的额外步骤对于链中的所有证书,而不仅仅是根证书都执行此操作! (在我的案例中,有三个:我的组织、中间证书和根证书)

然后... 进入Spring应用程序上下文配置XML文件,修改<http:conduit部分以获取Java的cacerts文件的正确路径(和密码):

<http:tlsClientParameters>
  <sec:keyManagers keyPassword="changeit">
    <sec:keyStore type="JKS" password="changeit"
                  file="C:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"/> 
  </sec:keyManagers>
  <sec:trustManagers>
    <sec:keyStore type="JKS" password="changeit"
                  file="C:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"/> 
  </sec:trustManagers>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接