I have a cxf service running on
https:
with the required client certificate. WSDL is not important here.
I can call the service when deleting a client certificate or https request.
Service and client classes were generated using the cxf wsdl2java utility.
Here is MyService.class:
package com.mycompany; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.WebEndpoint; import javax.xml.ws.WebServiceClient; import javax.xml.ws.WebServiceFeature; @WebServiceClient(name = "MyService", wsdlLocation = "myservice.wsdl", targetNamespace = "http://server/schemas/services") public class MyService extends Service { public final static URL WSDL_LOCATION; public final static QName SERVICE = new QName("http://server/schemas/services", "MyService"); public final static QName MyServicePort = new QName("http://server/schemas/services", "MyServicePort"); static { URL url = MyService.class.getResource("myservice.wsdl"); if (url == null) { Logger.getLogger(MyService.class.getName()).log(Level.INFO, "Can not initialize the default wsdl from {0}", "myservice.wsdl"); } WSDL_LOCATION = url; } public MyService(URL wsdlLocation) { super(wsdlLocation, SERVICE); } public MyService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public MyService() { super(WSDL_LOCATION, SERVICE); } @WebEndpoint(name = "MyServicePort") public MyServicePortType getMyServicePort() { return super.getPort(MyServicePort, MyServicePortType.class); } @WebEndpoint(name = "MyServicePort") public MyServicePortType getMyServicePort(WebServiceFeature... features) { return super.getPort(MyServicePort, MyServicePortType.class, features); } }
Here is my client without a client certificate requirement: (this works fine)
package com.mycompany; import java.net.URL; import javax.xml.namespace.QName; import com.mycompany.IdHolder; import com.mycompany.MyDataObject; public class CxfClientSslTest { public static void main(String[] args) { try { QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService"); URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl"); MyService ss = new MyService(wsdlURL, SERVICE_NAME); MyServicePortType port = ss.getMyServicePort(); IdHolder mensagem = new IdHolder(); mensagem.setId(1L); MyDataObject dataObject = port.getById(mensagem); System.out.println("Id: " + dataObject.getId()); } catch (Exception e) { e.printStackTrace(); } } }
And so my client will send their certificate:
package com.mycompany; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.xml.namespace.QName; import org.apache.cxf.configuration.jsse.TLSClientParameters; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.transport.http.HTTPConduit; public class CxfClientSslTest { public static void main(String[] args) { try { QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService"); URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl"); MyService ss = new MyService(wsdlURL, SERVICE_NAME); MyServicePortType port = ss.getMyServicePort(); tslIt(port); IdHolder mensagem = new IdHolder(); mensagem.setId(1L); MyDataObject dataObject = port.getById(mensagem); System.out.println("Id: " + dataObject.getId()); } catch (Exception e) { e.printStackTrace(); } } public static void tslIt(MyServicePortType port) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException { Client client = ClientProxy.getClient(port); HTTPConduit http = (HTTPConduit) client.getConduit(); TLSClientParameters tlsClientParameters = http.getTlsClientParameters(); KeyStore keyStore = getKeyStore(); KeyStore trustStore = getTrustStore(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, "123456".toCharArray()); KeyManager[] keyMgrs = keyManagerFactory.getKeyManagers(); tlsClientParameters.setKeyManagers(keyMgrs); trustManagerFactory.init(trustStore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); tlsClientParameters.setTrustManagers(trustManagers); tlsClientParameters.setDisableCNCheck(true); } public static KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { URL keyStoreUrl = CxfClientSslTest.class.getResource("/certs/client.jks"); File keystoreFile = new File(keyStoreUrl.getPath()); if (!keystoreFile.exists()) { throw new RuntimeException("keystore doesn't exists: " + keystoreFile.getAbsolutePath()); } KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream keystoreInput = new FileInputStream(keystoreFile.getAbsolutePath()); keystore.load(keystoreInput, "changeit".toCharArray()); keystoreInput.close(); return keystore; } public static KeyStore getTrustStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { URL trustStoreUrl = CxfClientSslTest.class.getResource("/certs/client-trust.jks"); File trustStoreFile = new File(trustStoreUrl.getPath()); if (!trustStoreFile.exists()) { throw new RuntimeException("truststore doesn't exists: " + trustStoreFile.getAbsolutePath()); } KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream trustStoreInput = new FileInputStream(trustStoreFile.getAbsolutePath()); trustStore.load(trustStoreInput, "changeit".toCharArray()); trustStoreInput.close(); return trustStore; } }
The TLS configuration from both the client and the server has been verified and is in order. But when I run the program, I get the following:
Information: Can not initialize the default wsdl from myservice.wsdl javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service. at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149) at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:98) at javax.xml.ws.Service.<init>(Service.java:77) at com.mycompany.MyService.<init>(MyService.java:36) at com.mycompany.CxfClientSslTest.main(CxfClientSslTest.java:32) Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service. at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:100) at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:199) at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:147) ... 4 more Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'https://localhost:8443/services/MyService?wsdl'.: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(Unknown Source) at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source) at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source) at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:262) at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:205) at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:98) ... 6 more Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1337) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:523) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1296) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653) at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:799) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:240) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:300) ... 12 more Caused by: java.security.cert.CertificateException: No name matching localhost found at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:208) at sun.security.util.HostnameChecker.match(HostnameChecker.java:93) at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:347) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:203) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1319) ... 30 more
I see that the problem occurs before my https configuration is done when cxf tries to load wsdl.
I did research on how to get cxf to use this https configuration to download wsdl. I need a lot of time, but I can not find the answer.
So my question is: how to get cxf to use the https configuration to load wsdl?
Please, I already have an answer, and I intend to put it here. So, if you do not have a good answer or a better answer, please do not post it.