Friday, December 12, 2008

How to solve the https SSL client authentication ava.security.cert.CertificateException: No name matching problem

javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://localhost:8443/WSRM/WsrmServerService?wsdl. It failed with:
java.security.cert.CertificateException: No name matching localhost found.
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:162)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:144)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:264)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:227)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:175)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
at javax.xml.ws.Service.(Service.java:56)
--------------------------------------------------------

Transport Security (SSL) Workaround

This note applies to cases where https is the transport protocol used between a WSIT client and a secure web service using transport binding, and you are referencing localhost when creating the client.


Note: If you use the fully-qualified hostname (FQHN) in the URL for the service WSDL when you are adding the web service client to the client application, this workaround is not required. It is only required when you specify localhost in the URL for the service WSDL.


During development (not production) it is sometimes convenient to use certificates whose CN (Common Name) does not match the host name in the URL.

A developer would want to use a CN which is different from the host name in the URL in WSIT when using https addresses in Dispatch clients and during wsimport. The below mentioned workaround is only for the Dispatch clients, which are also used in WS-Trust to communicate with STS. This has to be done even if the client's main service is not on https, but only the STS is on https.

Java by default verifies that the certificate CN (Common Name) is the same as host name in the URL. If the CN in the certificate is not the same as the host name, your web service client fails with the following exception:

javax.xml.ws.WebServiceException: java.io.IOException: HTTPS
hostname wrong: should be

The recommended way to overcome this issue is to generate the server certificate with the Common Name (CN) matching the host name.

To workaround this only during development, in your client code, you can set the default host name verifier to a custom host name verifier which does a custom check. An example is given below. It is sometimes necessary to include this in the static block of your main Java class as shown below to set this verifier before any connections are made to the server.

static {
//WORKAROUND. TO BE REMOVED.


javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

public boolean verify(String |hostname|,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("mytargethostname")) {
return true;
}
return false;
}
});
}

No comments: