we had a client made with Apache CXF which was working Ok, using certain server(i.e: https://serverexample.com/application/webservice?wsdl).
But the server has moved to another IP, and now it has two SSL Certificates with TLS and SNI(Server Name Indication) in the same IP, and now our applications fails with this error:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching serverexample.com found
I understand that this occurs when the https is getting the wrong certificate (it has another server name), and thus is not matching mine.
I tried to find out what happening with openssl, and the url only works if I put servername:
# openssl s_client -connect serverexample.com:443 -tls1
Certificate chain
0 s:/CN=otherserver.com/OU=Servers/O=MyOrganization/C=ES
i:/CN=ACV20/OU=PKACV/O=ACV/C=ES
# openssl s_client -connect serverexample.com:443 -servername serverexample.com
Certificate chain
0 s:/CN=serverexample.com/OU=Servers/O=MyOrganization/C=ES
i:/CN=ACV220/OU=PKACV1/O=ACV2/C=ES
The error happened in the generated apache client in this point:
final URL wsdlURL = new URL("https://serverexample.com/application/webservice?wsdl");
final Operation_Service ss = new Operation_Service(wsdlURL, SERVICE_NAME);
Fails in the new Operation_Service:
@WebServiceClient(name = "ENI.Operation",
wsdlLocation = "https://serverexample.com/application/webservice?wsdl",
targetNamespace = "http://inter.ra.es/awrp/wsdl")
public class Operation_Service extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://inter.ra.es/awrp/wsdl", "ENI.Operation");
public final static QName Operation = new QName("http://inter.ra.es/awrp/wsdl", "ENI.Operation");
static {
URL url = null;
try {
url = new URL("https://serverexample.com/application/webservice?wsdl");
} catch (final MalformedURLException e) {
java.util.logging.Logger.getLogger(Operation_Service.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "https://serverexample.com/application/webservice?wsdl");
}
WSDL_LOCATION = url;
}
public Operation_Service(final URL wsdlLocation, final QName serviceName) {
super(wsdlLocation, serviceName);
}
javax.xml.ws.Service calls javax.xml.ws.spi.ServiceDelegate, an abastract class implemented by some class in org.apache.cxf.jaxws.. but here I'm losing it, I don't know what to look...
Our client is runnring in java 7.0 with apache cxf 3.0.4 on a weblogic 12.1.1.0. I read that in Java 6 there was problems with SNI, but we are using 7.0 here.
I don't know what can I do. Is there some option in java or in our client to indicate the servername (like in openssl) we're trying to connect?
It is a combination of "improvements" in JDK 1.8 and the fact that the server has several certificates.
What is broken in JDK 1.8 is explained here: http://lea-ka.blogspot.com/2015/09/wtf-collection-how-not-to-add-api.html
It goes like this:
The easiest fix is to download all WSDL and XSD files and package them somewhere in your jar.
If you really need to fetch the WSDL from the remote server, this might help:
final URL wsdlURL = new URL("https://otherserver.com/application/webservice?wsdl");
But this might not work because "/application/webservice" might be known only to serverexample.com. In this case you get TLS connection and then HTTP 404 response code.
If this does not work you will have to resort to all sorts of SSL factories (which is verbose but sure possible) and attempts to hook them into javax.ws.... classes (which should be possible but I have never done that part).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With