简体   繁体   English

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

[英]Spring Boot: Use specific alias form keystore to consume HTTPS SOAP webservice

I have a spring boot application in which am trying to consume consume HTTPS SOAP webservice which requires authentication with private key which is part of my keystore.jks as alias client 我有一个春季启动应用程序,正在其中尝试使用消耗HTTPS SOAP Web服务,它需要使用私钥进行身份验证,这是我的keystore.jks的一部分,作为别名client

I have a spring boot application with below config 我有一个配置以下的Spring Boot应用程序

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 has 2 aliases(PFX) tomcat which serves the hosted service and client for authenticating with SOAP web service keystore.jks具有2个别名(PFX) tomcat ,用于为托管服务和client提供SOAP Web服务身份验证

I am seeing below exception when am trying to invoke java soap client stub 我在尝试调用Java Soap客户端存根时看到以下异常

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

Looks like client alias from keystore.jks is not used for authenticating with HTTPS web service, is there anyway I can force spring boot to use specific alias from keystore ? 看起来像来自keystore.jks client别名未用于通过HTTPS Web服务进行身份验证,是否仍然可以强制Spring Boot使用来自keystore特定别名? Or is there any workaround to achieve this? 还是有任何解决方法来实现这一目标?

Try this code to create a trust manager that does not validate certificate chains. 尝试使用此代码创建不验证证书链的信任管理器。 Hope this is a work around for your issue. 希望这能解决您的问题。

SSLTool.java 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) {}
          }
        }

and call the method before you consume the HTTPS SOAP webservice. 并在使用HTTPS SOAP Web服务之前调用该方法。

    new SSLTool();
    SSLTool.disableCertificateValidation();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM