Spring Boot出现PKIX路径构建失败错误,Postman配置证书可正常请求
问题分析与解决方案
你遇到的PKIX path building failed错误,核心原因是Spring Boot的RestTemplate作为客户端时,不信任目标服务(sandbox.sample.com)的SSL证书——Postman里你关闭了SSL证书验证所以能成功,但Spring Boot默认会严格验证服务端证书的合法性,而你的配置只添加了客户端证书,没处理服务端证书的信任问题,另外还混淆了服务端和客户端的SSL配置。
第一步:修正配置误区
你的application.properties里的server.ssl相关配置是给当前Spring Boot应用作为HTTPS服务端用的,和RestTemplate作为客户端调用外部服务完全无关,直接删掉这两行:
server.ssl.enabled=true server.ssl.bundle=client
第二步:解决服务端证书信任问题
针对测试环境和生产环境,有两种处理方式:
方式一:测试环境临时关闭SSL验证(不推荐生产)
如果只是测试用,可以让RestTemplate跳过服务端证书验证,同时保留客户端证书配置:
@Bean RestTemplate restTemplate(RestTemplateBuilder builder, SslBundles sslBundles) throws NoSuchAlgorithmException, KeyManagementException { // 获取客户端SSL bundle SslBundle sslBundle = sslBundles.getBundle("client"); // 创建跳过证书验证的SSL上下文 SSLContext sslContext = SSLContexts.custom() .loadKeyMaterial(sslBundle.getKeyStore(), sslBundle.getKeyStorePassword().toCharArray()) .loadTrustMaterial((chain, authType) -> true) // 信任所有证书 .build(); // 配置HttpClient HttpClient httpClient = HttpClientBuilder.create() .setSSLContext(sslContext) .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) // 跳过主机名验证 .build(); // 包装成ClientHttpRequestFactory HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); return builder .requestFactory(() -> requestFactory) .build(); }
方式二:生产环境添加服务端证书到信任库
- 先获取sandbox.sample.com的证书(可以用浏览器导出,或者用
openssl s_client -connect sandbox.sample.com:443 < /dev/null | openssl x509 -outform PEM > server-cert.pem命令生成) - 将证书文件放到项目的
cert目录下 - 修改
application.properties,添加信任库配置:
spring.ssl.bundle.pem.client.keystore.certificate=cert/sample.pem spring.ssl.bundle.pem.client.keystore.private-key=cert/sample.key # 添加服务端证书到信任库 spring.ssl.bundle.pem.client.truststore.certificate=cert/server-cert.pem
- 保持原来的RestTemplate配置即可:
@Bean RestTemplate restTemplate(RestTemplateBuilder builder, SslBundles sslBundles) { return builder .setSslBundle(sslBundles.getBundle("client")) .build(); }
额外注意事项
- 确保
cert目录在项目的resources下,或者配置路径时使用绝对路径 - 如果你的
sample.key是加密的,需要在application.properties里添加spring.ssl.bundle.pem.client.keystore.private-key-password=你的密钥密码
内容的提问来源于stack exchange,提问作者RedBlue
相关产品推荐
相关产品推荐

