Shane
Shane

Reputation: 21

SOAP webservice connection through SSL

i'm trying to write a java based webservice client to consume a secure webservice over netting IP. This is my first time so i need some serious help here please. All i get from my vendor is three different .cer files and a wsdl link. After some research what i did that created a new keystore with keytool -import -file myCert.cer -alias testkey -keystore test.ks and added these three .cer files into it, nothing else. Then i wrote below code for testing. Tell me if anything else i need to do to make a successful connection.

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.nio.charset.Charset;

import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

public class SOAPClient {

public static void main(String[] args) {
    String response = null;
    try {
        String request = "my xml based SOAP string";

        System.setProperty("javax.net.ssl.keyStore", "/web/cert/test.ks"); 
        System.setProperty("javax.net.ssl.keyStorePassword", "password");

        // Create SOAP Connection
        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();

        String url = "https://example.com:31746/Service/service.serviceagent";
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPConnection soapConnection = soapConnectionFactory.createConnection();

        SOAPMessage soapMessage = messageFactory.createMessage(new MimeHeaders(), new ByteArrayInputStream(request.getBytes(Charset.forName("UTF-8"))));

        // Send SOAP Message to SOAP Server
        SOAPMessage soapResponse = soapConnection.call(soapMessage, url);

        // Process the SOAP Response
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Source sourceContent = soapResponse.getSOAPPart().getContent();
        StringWriter outWriter = new StringWriter();
        StreamResult result = new StreamResult( outWriter );
        transformer.transform(sourceContent, result);  
        StringBuffer sb = outWriter.getBuffer(); 
        response = sb.toString();
        System.out.println(response);

        soapConnection.close();
    } catch (Exception e) {
        System.err.println("Error occurred while sending SOAP Request to Server");
        e.printStackTrace();
    }
    //return response;
}

}

But when i run this java code as a standalone through command line (as i have no other way of testing it) i get below exceptions on screen.

 %% Cached client session: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
 main, WRITE: TLSv1 Application Data, length = 352
 main, WRITE: TLSv1 Application Data, length = 32
 main, WRITE: TLSv1 Application Data, length = 960
 main, READ: TLSv1 Application Data, length = 208
 main, called close()
 main, called closeInternal(true)
 main, SEND TLSv1 ALERT:  warning, description = close_notify
 main, WRITE: TLSv1 Alert, length = 32
 main, called closeSocket(selfInitiated)
 Dec 16, 2016 11:51:54 AM com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection post
 SEVERE: SAAJ0010: Unable to read response
 java.lang.NullPointerException
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.readFully(HttpSOAPConnection.java:544)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:313)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)

 Error occurred while sending SOAP Request to Server
 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to
 read response: null
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:148)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)
 Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to read response: null
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:337)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         ... 1 more

 CAUSE:

 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to read response: null
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:337)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)

 CAUSE:

 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to read response: null
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:337)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)

UPDATE

If i put ?wsdl in the end of URL. I get below exception

 Dec 16, 2016 1:01:16 PM com.sun.xml.internal.messaging.saaj.soap.MessageImpl identifyContentType
 SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
 Error occurred while sending SOAP Request to Server
 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Co
 ntent-Type:text/html. Is this an error message instead of a SOAP response?
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:148)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)
 Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error messa
 ge instead of a SOAP response?
         at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.identifyContentType(MessageImpl.java:655)
         at com.sun.xml.internal.messaging.saaj.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:85)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:327)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         ... 1 more

 CAUSE:

 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead
 of a SOAP response?
         at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.identifyContentType(MessageImpl.java:655)
         at com.sun.xml.internal.messaging.saaj.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:85)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:327)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)

 CAUSE:

 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead
 of a SOAP response?
         at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.identifyContentType(MessageImpl.java:655)
         at com.sun.xml.internal.messaging.saaj.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:85)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:327)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         at AKUSOAPClient.main(AKUSOAPClient.java:32)

UPDATE 2

After changing property from keystore to truststore

 %% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
 main, SEND TLSv1 ALERT:  fatal, description = certificate_unknown
 main, WRITE: TLSv1 Alert, length = 2
 main, called closeSocket()
 main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path buil
 ding failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requ
 ested target
 main, called close()
 main, called closeInternal(true)
 Dec 16, 2016 4:50:49 PM com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection post
 SEVERE: SAAJ0009: Message send failed
 Error occurred while sending SOAP Request to Server
 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message se
 nd failed
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:148)
         at AKUSOAPClient.main(AKUSOAPClient.java:34)
 Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:278)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)
         ... 1 more
 Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: su
 n.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
         at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
         at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1904)
         at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
         at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:273)
         at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1446)
         at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209)
         at sun.security.ssl.Handshaker.processLoop(Handshaker.java:901)
         at sun.security.ssl.Handshaker.process_record(Handshaker.java:837)
         at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1023)
         at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
         at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
         at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
         at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
         at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java
 :185)
         at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1092)
         at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
         at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:235)
         ... 2 more
 Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertP
 athBuilderException: unable to find valid certification path to requested target
         at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
         at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
         at sun.security.validator.Validator.validate(Validator.java:260)
         at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
         at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
         at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
         at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1428)
         ... 14 more
 Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to reques
 ted target
         at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
         at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
         at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
         ... 20 more

Upvotes: 2

Views: 4567

Answers (1)

pedrofb
pedrofb

Reputation: 39291

I think this is not the underlying issue, but you need you change javax.net.ssl.keyStore by javax.net.ssl.trustStore.

  • The trustStore determines whether the remote authenticationcredentials (and thus the connection) should be trusted.

  • The keyStore determines which authentication credentials to send to the remote host.

Probably the error is due to your request is not a valid SOAP message, and it is causing a null response from server.

String request = "my xml based SOAP string";

I suggest you debug the soap messages interchanged and use a JAX-WS client generated from WSDL instead of building the SOAP messages from scratch

Upvotes: 2

Related Questions