First, I’ll start with a summary. I’m using an Apache CXF client to communicate over SSL with an Apache CXF service provider that is using a self-signed certificate. I imported the certificate into the WebSphere truststore on the client server, but I still receive a “javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://somesvcprovider.com/appname/svc/myservice: com.ibm.jsse2.util.h: No trusted certificate found” exception.
Now, here’s the details:
I have an Apache CXF web service client that I am configuring using Spring, and the client is deployed to a WebSphere 6.1 application server. The CXF client communicates with an Apache CXF service provider on a different WebSphere server. The communication uses SSL.
The service provider is using a self-signed certificate. I’ve imported the provider’s certificate into the WebSphere truststore on the client server through the administrative console. I accomplished this by going to SSL certificate and key management > SSL configurations > NodeDefaultSSLSettings > Key stores and certificates > NodeDefaultTrustStore > Signer certificates; then I used the “Retrieve from port” tool to import the certificate.
However, I still receive this error when attempting to contact the service provider: “javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://somesvcprovider.com/appname/svc/myservice: com.ibm.jsse2.util.h: No trusted certificate found”.
The Spring configuration file is as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<http:conduit name="*.http-conduit">
<!-- deactivate HTTPS url hostname verification (localhost, etc) -->
<!-- WARNING ! disableCNcheck=true should not used in production. -->
<http:tlsClientParameters disableCNCheck="true" />
</http:conduit>
<!-- Read properties from property file(s). -->
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- The *.spring.properties files are prefixed with a system property
that is set on the WebSphere server. -->
<value>classpath:spring.${my.env}.properties</value>
</list>
</property>
</bean>
<jaxws:client id="myServiceClient"
serviceClass="com.client.stub.cxf.IMyService"
address="${my.svc.url}" />
<bean id="myReport" class="com.client.MyReportRequestor">
<property name="client" ref="myServiceClient"/>
</bean>
</beans>
As shown above, the CXF client is injected via a setter by Spring. The code to contact the service is below:
List<String> formNames = client.retrieveNames(formIdsList);
Also, I don’t know if this is related, but no trust managers are returned when I inspect the TLSClientParameters object on the CXF client at runtime. The code to do the inspection is below:
// Get the trust managers for this client.
Client proxy = ClientProxy.getClient(client);
HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
TLSClientParameters tls = conduit.getTlsClientParameters();
TrustManager[] trustManagers = tls.getTrustManagers(); // trustManagers is null
Is there anything else that I need to do to get the Apache CXF client to trust the self-signed certificate?
I prefer to not have to specify the path to a truststore along with a password in the configuration file.
Thank you!
I don’t think you can use the WAS keystores just like that with external component (Apache CXF). You must probably build and use your own TrustManager. There seem to be several working examples around for that.