Search code examples
sslsoapwebspherecxfjax-ws

Using wsimport to create a SOAP client but unable to get it to work with SSL certificate


It's been a while since I've had to do any Java development, so perhaps I'm a bit rusty. However, I've been tasked with creating a SOAP client that will be called within a IBM HATS (web) application. No problem! I'm using Rational Application Developer 9.7.0.1 and I simply imported the WSDL and generated the client classes. The issue, though, is that this service requires an SSL certificate. I've tried a ton of different things, but nothing I've done has been able to get this to work. In addition to RAD 9.7.0.1, I'm using WebSphere Application Server 9 and Java 1.8.0_251. I wanted to stick with just vanilla JAX-WS instead of introducing CXF/Spring. So the first thing I tried was just setting the truststore properties:

System.setProperty("javax.net.ssl.trustStore", "C:\\keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "******");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");

This still gives me the error an error that the certificate could not be found.

So I bit the bullet and tried using CXF 3.3.7 to set up the HTTPS connection -

//Set Up SSL Connection
SSLContext sslContext = null;
try
{
    KeyStore trustStoreInst = KeyStore.getInstance("JKS");
             
    trustStoreInst.load(CMPIDCASCustom.class.getClassLoader().getResourceAsStream(trustStore), 
                                                              trustStorePassword.toCharArray());
        
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
    tmf.init(trustStoreInst);
            
    sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
}
catch (Exception e)
{
    e.printStackTrace();
}
                
//Call the Service
SoaProxy service = new SoaProxy();
SoaProxySoap servicePort = service.getSoaProxySoap();
        
BindingProvider provider = (BindingProvider)servicePort;
provider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
                                 "https://myurl.com/soaproxy.asmx");
        
Client client = ClientProxy.getClient(servicePort);
HTTPConduit http = (HTTPConduit) client.getConduit();
        
TLSClientParameters parameters = new TLSClientParameters();
parameters.setSSLSocketFactory(sslContext.getSocketFactory());
http.setTlsClientParameters(parameters);
        
UserResponse userResponse =  servicePort.retrieveUser(param1, param2);

However, doing this gives me the following error: org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler incompatible with org.apache.cxf.frontend.ClientProxy java.lang.ClassCastException: org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler incompatible with org.apache.cxf.frontend.ClientProxy

This seems to be a well-known error, however, trying to:

  1. Upgrade org.apache.ws.commons.schema.XmlSchemaCollection
  2. Adding this code:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("https://blwq-auth.betasys.com/tsaproxyservice/soaproxy.asmx?wsdl");
factory.setServiceClass(SoaProxySoap.class);
SoaProxySoap servicePort = (SoaProxySoap) factory.create();
  1. Or setting DisableIBMJAXWSEngine to true in my Manifest.mf and in the admin console does not seem to work.

Does anyone know the quickest, easiest way to get a SOAP client to work with an SSL certificate whether it be just using JAX-WS itself or with CXF? Thank you!!!


Solution

  • Assuming the client application is running inside WebSphere, the certificate from the web service needs to be added to WebSphere's trust store. I found the process to do that here: https://www.ibm.com/support/knowledgecenter/en/SSRMWJ_6.0.0.4/com.ibm.isim.doc_6.0.0.4/installing/tsk/tsk_ic_config_was_ssl_dbservr.htm (different product, but the process is the same.)