【问题标题】:Spring RestTemplate conflicts with javax.net.ssl.trustStorePassword and javax.net.ssl.trustStoreSpring RestTemplate 与 javax.net.ssl.trustStorePassword 和 javax.net.ssl.trustStore 冲突
【发布时间】:2026-01-10 03:35:01
【问题描述】:

我们正在开发一个通过Socket 连接到外部服务器的项目,连接类型是ssl。 证书是自签名的,项目代码设置System Property 以通过类似这样的方式通过证书验证:

System.setProperty("javax.net.ssl.trustStorePassword", .....);
System.setProperty("javax.net.ssl.trustStore", ....);

我们正在尝试扩展项目并使用Spring RestTemplate。但是发生了一些奇怪的事情!

当我们创建并注入一个新的RestTemplate 对象时,旧代码停止工作,我得到unable to find valid certification path to requested target

这些代码在对象中既没有共同点,也没有源代码......

发生了什么? Spring RestTemplate 是否更改或影响系统属性?

【问题讨论】:

    标签: sockets ssl certificate spring-rest


    【解决方案1】:

    我发现默认的 Apache HttpComponent 会导致错误。我也不知道为什么!!

    我切换到OKHttp3。旧代码继续工作。

    这是一个示例代码:

    因为它是自签名证书,所以我将它们从商店添加到 OkkHttp HandshakeCertificates

            List<X509Certificate> certificates = getCertificatesFromTrustStore();
            
            Builder certificateBuilder =  new HandshakeCertificates.Builder();        
            for (X509Certificate x509Certificate : certificates) {
                certificateBuilder.addTrustedCertificate(x509Certificate);
            }
            HandshakeCertificates handshakeCertificates =  certificateBuilder.build();
    
            ConnectionPool okHttpConnectionPool = new ConnectionPool(MAX_IDLE_CONNETION, KEEP_ALIVE_DURATION, TimeUnit.SECONDS);
            
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                        .hostnameVerifier(new NoopHostnameVerifier())       
                        .retryOnConnectionFailure(false)
                        .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                        .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager())
                        .connectionPool(okHttpConnectionPool)
                        .build();
                
            ClientHttpRequestFactory clientHttpRequestFactory =  new OkHttp3ClientHttpRequestFactory(okHttpClient);
            
            RestTemplate restTemplate = new RestTemplate(
                    new BufferingClientHttpRequestFactory(
                            clientHttpRequestFactory
                    ));    
    
            //Set error handler
            MyRestTemplateResponseErrorHandler errorHandler = new MyRestTemplateResponseErrorHandler();
            errorHandler.setMessageConverters(restTemplate.getMessageConverters());
            restTemplate.setErrorHandler(errorHandler);
            
            return restTemplate;
        }
    
        private List<X509Certificate> getCertificatesFromTrustStore() throws KeyStoreException, IOException,
                NoSuchAlgorithmException, CertificateException, FileNotFoundException, InvalidAlgorithmParameterException {
            KeyStore truststore = KeyStore.getInstance("JKS");
            truststore.load(new FileInputStream(trustStorePath), keystorePass.toCharArray());
            
            Set<TrustAnchor> trustAnchors = new PKIXParameters(truststore).getTrustAnchors();
            LOG.debug("{} certificates found in {} which will be used", trustAnchors.size(), trustStorePath);
            
            List<X509Certificate> certificates = trustAnchors.stream()
                      .map(TrustAnchor::getTrustedCert)
                      .collect(Collectors.toList());
            return certificates;
        }
    

    【讨论】:

      最近更新 更多