如何使用证书在 Spring Boot 中调用 https Web 服务

Posted

技术标签:

【中文标题】如何使用证书在 Spring Boot 中调用 https Web 服务【英文标题】:How to call https webserivce in spring boot with certificate 【发布时间】:2016-10-13 04:59:03 【问题描述】:

在使用 apache cxf face 在 Spring Boot 中调用 https 网络服务时出现以下异常

调用https://fanava.shaparak.ir:443/merchantwebservice/jax/merchantAuth的SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

调用此服务需要哪些配置?

类客户端:

@Configuration
public class WSClient 
   @Bean(name = "PaymentWebService")
   public PaymentWebService PaymentWebServiceCLient() throws MalformedURLException 
          JaxWsProxyFactoryBean factory;
          factory = new JaxWsProxyFactoryBean();
          factory.setServiceClass(PaymentWebService.class);
          factory.setAddress("http://localhost:8080/soap-api/merchantAuth_1.0");
          return (PaymentWebService) factory.create();
   

【问题讨论】:

【参考方案1】:

网站的根证书不在 JVM 信任库中。所以如果你把根证书导入<path_to>/jre/lib/security/cacerts我想你会没事的。

【讨论】:

请解释一下,如果可以描述配置步骤。【参考方案2】:

1.获取你想要的证书webservice。

2.使用此证书创建密钥库。

3.ssl 使用密钥库配置客户端:

@Configuration
public class WebServiceClient 

@Inject
private PaymentProperties paymentProperties;

@Autowired
private ResourceLoader resourceLoader;

@Bean(name = "PaymentWebService")
public PaymentWebService PaymentWebServiceCLient() throws MalformedURLException 

    JaxWsProxyFactoryBean factory;
    factory = new JaxWsProxyFactoryBean();
    factory.setServiceClass(PaymentWebService.class);
    // factory.setAddress("http://localhost:8080/ws/merchantAuth_1.0");
    factory.setAddress(paymentProperties.getWsPublicUrl());

    PaymentWebService service = (PaymentWebService) factory.create();
    try 
        final Client client = ClientProxy.getClient(service);
        setupSsl((HTTPConduit) ClientProxy.getClient(service).getConduit());
     catch (Exception e) 
    
    return service;


private void setupSsl(HTTPConduit httpConduit) throws Exception 

    final TLSClientParameters tlsCP = new TLSClientParameters();

    final String keyStoreLoc = paymentProperties.getSsl().getKeyStore();
    final String keyPassword = paymentProperties.getSsl().getKeyStorePassword();
    final String keystoreType = paymentProperties.getSsl().getKeyStoreType();

    final KeyStore keyStore = KeyStore.getInstance(keystoreType);
    Resource resource1 = resourceLoader.getResource(keyStoreLoc);
    keyStore.load(resource1.getInputStream(), keyPassword.toCharArray());
    final KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);
    tlsCP.setKeyManagers(myKeyManagers);

    final String trustStoreLoc = paymentProperties.getSsl().getTrustStore();
    final String trustStorePassword = paymentProperties.getSsl().getTrustStorePassword();
    final String trustStoreType = paymentProperties.getSsl().getTrustStoreType();

    final KeyStore trustStore = KeyStore.getInstance(trustStoreType);
    Resource resource2 = resourceLoader.getResource(trustStoreLoc);
    trustStore.load(resource2.getInputStream(), trustStorePassword.toCharArray());
    final TrustManager[] myTrustStoreKeyManagers = getTrustManagers(trustStore);
    tlsCP.setTrustManagers(myTrustStoreKeyManagers);

    httpConduit.setTlsClientParameters(tlsCP);


private static TrustManager[] getTrustManagers(KeyStore trustStore)
        throws NoSuchAlgorithmException, KeyStoreException 
    String alg = KeyManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory fac = TrustManagerFactory.getInstance(alg);
    fac.init(trustStore);
    return fac.getTrustManagers();


private static KeyManager[] getKeyManagers(KeyStore keyStore, String keyPassword)
        throws GeneralSecurityException, IOException 
    String alg = KeyManagerFactory.getDefaultAlgorithm();
    char[] keyPass = keyPassword != null ? keyPassword.toCharArray() : null;
    KeyManagerFactory fac = KeyManagerFactory.getInstance(alg);
    fac.init(keyStore, keyPass);
    return fac.getKeyManagers();


【讨论】:

以上是关于如何使用证书在 Spring Boot 中调用 https Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot - 调用另一个需要证书的 Web 服务

如何设置letsencrypt SSL证书并在Spring Boot应用程序中使用它?

具有有效证书的spring boot https获取ERR_SSL_VERSION_OR_CIPHER_MISMATCH,自签名工作正常

spring boot ssl 客户端证书失败,PKIX 路径构建失败错误

Spring Boot如何配置SSL实现https协议

如何配置 Spring Boot 应用程序以接受未知的 SSL 客户端证书?