Spring Boot:使用特定的别名表单密钥库来使用HTTPS SOAP webservice

时间:2017-04-19 00:26:16

标签: java web-services soap spring-boot groovy

我有一个spring boot应用程序,其中我尝试使用HTTPS SOAP webservice,这需要使用私钥进行身份验证,这是我的keystore.jks的一部分,作为别名client

我有一个带有以下配置的弹簧启动应用程序

server:  
  port: 8443
  sessionTimeout: 30
  ssl:
    key-store: keystore.jks
    key-store-password: 123456    
    keyAlias: tomcat
    key-password: 123456
    keyPassword: 123456
    trust-store: truststore.jks
    trust-store-password: 123456

keystore.jks有两个别名(PFX)tomcat,用于托管服务,client用于通过SOAP网络服务进行身份验证

我在尝试调用java soap client stub

时看到以下异常
%% Invalidated:  [Session-2, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
https-jsse-nio-443-exec-4, SEND TLSv1.2 ALERT:  fatal, description = certificate_unknown
https-jsse-nio-443-exec-4, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 2E                               .......
https-jsse-nio-443-exec-4, called closeSocket()
https-jsse-nio-443-exec-4, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
2017-04-18 17:15:26.253 ERROR 2360 --- [-nio-443-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://tseiod-test.trustweaver.com/ts/svs.asmx?wsdl. It failed with: 
    sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.] with root cause

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at java.net.URL.openStream(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
    at javax.xml.ws.Service.<init>(Unknown Source)

来自client的{​​{1}}别名似乎未用于使用HTTPS网络服务进行身份验证,无论如何我可以强制Spring引导使用来自keystore.jks的特定别名吗?或者有任何解决方法来实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

尝试使用此代码创建不验证证书链的信任管理器。 希望这是解决您问题的方法。

SSLTool.java

   import javax.net.ssl.*;
   import java.security.SecureRandom;
   import java.security.cert.X509Certificate;
    public class SSLTool {

          public static void disableCertificateValidation() {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] { 
              new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() { 
                  return new X509Certificate[0]; 
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }};

            // Ignore differences between given hostname and certificate hostname
            HostnameVerifier hv = new HostnameVerifier() {
              public boolean verify(String hostname, SSLSession session) { return true; }
            };

            // Install the all-trusting trust manager
            try {
              SSLContext sc = SSLContext.getInstance("SSL");
              sc.init(null, trustAllCerts, new SecureRandom());
              HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
              HttpsURLConnection.setDefaultHostnameVerifier(hv);
            } catch (Exception e) {}
          }
        }

并在使用HTTPS SOAP Web服务之前调用该方法。

    new SSLTool();
    SSLTool.disableCertificateValidation();