Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

java - CXF client: unable to find valid certification path to requested target

I am trying to implement a client for a CXF-based web service that I also wrote.

My web service works great (tested working fine via soapUI), but running the client fails with the following:

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)

The message clearly points at a certificate problem, so I did a quick search and found the correct approach to supporting SSL in CXF and added the following to my Spring application context config 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>

And rebuilt the client. The client built successfully but I am still getting the same exact error and same exact stack trace, as if I never added this http:conduit thing.

I have not added the certificate to the store yet, and the path to the store is incorrect, but this is intentional as I just wanted to see how the re-built client reports this problem, adjusting to the new http:conduit information.

Instead, I was surprised to see that it was ignored altogether.

What have I missed?

What is the correct way of approaching this?


Update: I just noticed my applicationcontext.xml underlining http:conduit with this error message:

The prefix "http" for element "http:conduit" is not bound.

So I did a quick search and found a thread that suggests:

The client needs to configure the HTTP conduit with the keystore that contains the certificate of the STS, e.g.:

 <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>

Which reinforces what @GreyBeardedGeek wrote. Going to work on this now...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Problem solved!

I followed this magicmonster article carefully (note the highlights on "older version of java", and the default password 'changeit'), to import the entire self signed certificate chain to the list of trusted certificates of the Java:

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

With one very important additional twist: Do it for all certificates in the chain, not only the root! (in my case there were three: my organization's, the intermediate, and the root)

Then... go to the Spring application context config XML and modify the <http:conduit section to have the correct path (and password) for Java's cacerts file:

<http:tlsClientParameters>
  <sec:keyManagers keyPassword="changeit">
    <sec:keyStore type="JKS" password="changeit"
                  file="C:Program Files (x86)Javajdk1.6.0_45jrelibsecuritycacerts"/> 
  </sec:keyManagers>
  <sec:trustManagers>
    <sec:keyStore type="JKS" password="changeit"
                  file="C:Program Files (x86)Javajdk1.6.0_45jrelibsecuritycacerts"/> 
  </sec:trustManagers>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...