通过SSL

时间:2016-12-16 08:22:48

标签: java ssl soap webservice-client saaj

我正在尝试编写一个基于Java的Web服务客户端,以通过网络IP来使用安全的Web服务。这是我的第一次,所以我需要一些认真的帮助。我从我的供应商那里获得的是三个不同的.cer文件和一个wsdl链接。经过一些研究我做了什么创建了一个带有keytool -import -file myCert.cer -alias testkey -keystore test.ks的新密钥库,并将这三个.cer文件添加到其中,没有别的。然后我写了下面的代码进行测试。告诉我是否需要做任何其他事情才能建立成功的连接。

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;
}

}

但是当我通过命令行将这个java代码作为独立程序运行时(因为我没有其他测试方法),我在屏幕上得到以下异常。

 %% 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)

更新

如果我将?wsdl放在网址末尾。我得到以下异常

 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)

更新2

将属性从keystore更改为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

1 个答案:

答案 0 :(得分:2)

我认为这不是潜在问题,但您需要按javax.net.ssl.keyStore更改javax.net.ssl.trustStore

  • trustStore 确定是否为远程 authenticationcredentials(以及连接)应该是 值得信赖的。

  • keyStore 确定要发送到的身份验证凭据 远程主机。

可能错误是由于您的请求不是有效的SOAP消息,并且它导致服务器的空响应。

String request = "my xml based SOAP string";

我建议您调试互换的soap消息并使用从WSDL生成的JAX-WS客户端,而不是从头开始构建SOAP消息