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:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("https://blwq-auth.betasys.com/tsaproxyservice/soaproxy.asmx?wsdl");
factory.setServiceClass(SoaProxySoap.class);
SoaProxySoap servicePort = (SoaProxySoap) factory.create();
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!!!
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.)