当前位置: 首页 > article >正文

SpringBoot3使用RestTemplate请求接口忽略SSL证书

概述

我在项目中使用SpringBoot3版本+中RestTemplate请求接口时候报错:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to fin

注意:springBoot3版本+RestTemplate对应的是spring-web-6.+版本旧版本不适用以下解决方案,构建RestTemplateConfigl类可能会找不到对应方法!!!

错误原因

在使用 RestTemplate 调用 HTTPS 接口时,出现 PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 错误,通常是因为 Java 应用程序无法验证服务器的 SSL 证书。

具体原因如下:

  1. 证书不受信任:Java 的默认信任库(cacerts)中没有包含服务器使用的 SSL 证书或中间证书。Java 使用这个信任库来验证服务器的证书链。

  2. 自签名证书:如果服务器使用的是自签名证书,而不是由受信任的证书颁发机构(CA)签发的证书,Java 默认不会信任这种证书。

  3. 证书链不完整:服务器的 SSL 证书链不完整,缺少中间证书,导致 Java 无法构建完整的证书路径。

解决方案

1. 将服务器证书添加到 Java 的信任库

如果服务器使用的是自签名证书或不受信任的证书,可以将该证书添加到 Java 的信任库中。

步骤:

  1. 获取服务器证书

    • 使用浏览器访问目标 HTTPS 接口,导出服务器的 SSL 证书。

    • 或者使用 openssl 命令获取证书:

openssl s_client -connect <服务器地址>:443 -showcerts
    • 将输出中的证书部分保存为 .crt 文件。

  1. 将证书导入 Java 信任库

    • 找到 Java 的 cacerts 文件,通常位于 $JAVA_HOME/lib/security/cacerts

    • 使用 keytool 将证书导入信任库:

keytool -import -trustcacerts -file <证书文件> -keystore $JAVA_HOME/lib/security/cacerts -alias <别名>
    • 默认密码是 changeit

  1. 重启应用程序:确保应用程序重新加载信任库。

2. 忽略 SSL 证书验证(不推荐)

如果你在开发环境中,且不关心证书验证,可以临时忽略 SSL 证书验证。注意:这种方法不安全,不推荐在生产环境中使用。

步骤:

  1. 自定义 RestTemplate

    • 创建一个自定义的 SSLContext,忽略证书验证。

    • 使用 NoopHostnameVerifier 忽略主机名验证。




import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.client5.http.ssl.TrustAllStrategy;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;


@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() throws Exception {
        HttpComponentsClientHttpRequestFactory factory = generateHttpRequestFactory();
        factory.setConnectTimeout(15000);
        factory.setConnectionRequestTimeout(5000);
        return factory;
    }

    /**
     * 构造跳过SSL ClientHttp工厂
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws KeyStoreException
     */
    public static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory()
            throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
        CloseableHttpClient httpclient = HttpClients.custom()
                .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
                        .setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
                                .setSslContext(SSLContextBuilder.create()
                                        .loadTrustMaterial(TrustAllStrategy.INSTANCE)
                                        .build())
                                .setHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                                .build())
                        .build())
                .build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setHttpClient(httpclient);
        return factory;
    }
}
  1. 使用自定义的 RestTemplate

    • 在调用 HTTPS 接口时,使用上述方法创建的 RestTemplate

3. 使用受信任的证书

如果可能,建议使用由受信任的 CA 签发的证书,而不是自签名证书。这样可以避免证书验证问题。

总结

  • 推荐方案:将服务器证书添加到 Java 的信任库中,确保证书链完整且受信任。

  • 临时方案:在开发环境中,可以临时忽略 SSL 证书验证,但不建议在生产环境中使用。

  • 最佳实践:使用受信任的 CA 签发的证书,确保 SSL/TLS 通信的安全性。


http://www.kler.cn/a/558276.html

相关文章:

  • 蓝桥备赛(一)- C++入门(上)
  • Unity贴图与模型相关知识
  • PostgreSQL‘会用‘到‘精通‘,学习感悟
  • 《论云上自动化运维及其应用》审题技巧 - 系统架构设计师
  • [原创](Modern C++)现代C++的关键性概念: std::span, 低内存开销的方式来操作大数据.
  • C语言--正序、逆序输出为奇数的位。
  • Spring Boot:开启快速开发新时代
  • 23种设计模式之《组合模式(Composite)》在c#中的应用及理解
  • ETL工具: Kettle入门(示例从oracle到oracle的数据导入)
  • 51单片机学习——动态数码管显示
  • ROS2 应用:按键控制 MoveIt2 中 Panda 机械臂关节位置
  • SAP 代码扫描工具
  • 鹰角基于 Flink + Paimon + Trino 构建湖仓一体化平台实践项目
  • Linux离线环境安装miniconda并导入依赖包
  • Spring 依赖注入实战指南:XML、注解、Java 配置全面对比
  • 备忘录模式:快速恢复原始数据
  • 图数据库Neo4j面试内容整理-关系类型
  • Linux 性能更好的ftp客户端 lftp 使用详解
  • PHP Libxml:深入解析XML解析库及其在PHP中的应用
  • 【WebGL】attribute方式实例化绘制