Search code examples
javasecuritysslhttpsjax-ws

How to build the EndPoint correctly using jax-ws?


I am using the bootstrap method to build my endpoints dynamically by making the WSDL available locally. For both http and https, but I am pretty sure I am going somewhere wrong while building them for https.

Map<String, Object> context = ((BindingProvider)control).getRequestContext();
URL address = mInstance.getConnectionEndpoint();
    if (address != null && Settings.getSettings().isUsingHttpConnection()) {
        context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,address.toString());
        System.out.println(address);
    }
    else{
        //for https

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
        {
            public boolean verify(String hostname, SSLSession session)
            {
                if (hostname.equals("myhostname"))
                    return true;
                return false;
            }
        });

        address = mInstance.getSecureConnectionEndpoint();
        context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,address.toString());
    }

Where getConnectionEndpoint and getSecureConnectionEndpoint look like:

   public URL getConnectionEndpoint() {
    URL url = null;
    try {
        int port = 50013;
        url = new URL("http", mHost.getHostAddress(), port, "");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    return url;
}

public URL getSecureConnectionEndpoint() {
    URL url = null;
    try {
        int port = 50014;
        url = new URL("https", mHost.getHostAddress(), port, "");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    return url;
}

This works fine when I use http. But for https I always end up getting this error that says:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

Obviously googling this error I found answers that it might be due to improper importing of the server and client SSL certificates in the Java TrustStore.

But I am pretty confident that the issue is not that.

The child errors of the parent error mentioned above look something like this:

at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)

I would be grateful to you if you can help me solve this issue! Cheers in advance.


Solution

  • The problem is likely that the value returned from mHost.getHostAddress() is a different hostname than the common name on the certificate offered by the server. For example, if localhost is the the value of mHost.getHostAddress() yet the SSL cert is issued to 127.0.0.1 (or vice versa) you may get this issue.

    This post identifies a code workaround in case regenerating and reinstalling the certificate with a different CN is not viable or desirable. It involves using the HostnameVerifier mechanism of HttpsUrlConnection.