exception记录:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certifi

本文介绍了一种解决Feign客户端在HTTPS环境下因SSL校验失败导致请求异常的方法,通过在pom.xml中引入feign-httpclient依赖,并在配置文件中设置disableSslValidation为true来禁用SSL校验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

解决: 禁用SSL校验

     (同事给的解决方案,特此记录一下)

   <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
  </dependency>

feign:
  httpclient:
    enabled: true
   disableSslValidation: true

### 关于PKIX Path Building Failed问题的解决方案 当遇到`PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path for requested target`错误时,通常是因为Java环境无法验证目标服务器的SSL证书链。以下是针对此问题的具体分析和解决方法。 #### 错误的根本原因 该错误的核心在于JDK的信任库(truststore)中缺少目标站点的有效CA证书[^1]。具体来说: - **HTTPS请求**需要通过SSL/TLS协议建立安全连接。 - Java会尝试验证目标站点的SSL证书是否由受信任的CA签发。 - 如果JDK的信任库中未包含对应的根证书,则会发生`PKIX path building failed`错误。 --- ### 解决方案一:导入目标站点的SSL证书到JDK信任库 可以通过手动将目标站点的SSL证书导入到JDK的信任库来解决问题: 1. 访问目标URL `https://qyapi.weixin.qq.com/cgi-bin/gettoken` 并导出其SSL证书。 - 使用浏览器访问页面并查看证书详情,将其保存为`.cer`文件。 2. 将证书导入到JDK的信任库中。 - 定位到JDK安装目录下的`\jre\lib\security\cacerts`文件。 - 打开命令行工具,执行以下命令: ```bash keytool -import -alias wechat_cert -keystore cacerts -file certificate.cer ``` 默认密码为`changeit`[^3]。 3. 验证证书已成功导入。 - 可以通过以下命令检查信任库中的证书列表: ```bash keytool -list -v -keystore cacerts | grep Alias ``` 完成以上操作后,重新运行程序即可正常发起HTTPS请求。 --- ### 解决方案二:禁用SSL证书校验(不推荐用于生产环境) 对于开发测试阶段,可以临时关闭SSL证书校验功能。需要注意的是,这种方法存在安全隐患,仅适用于调试场景。 实现方式如下: ```java package cn.com.webservice.WeChat; import javax.net.ssl.*; import java.security.cert.X509Certificate; import cn.com.webservice.util.HttpRequestUtil; public class AccessTokenTest { public static void main(String[] args) throws Exception{ disableSSLCertificateValidation(); // 调用方法禁用SSL校验 String corpid = "wxf9291cddfe5"; String corpsecret = "InWpADosVs7RXG5MwBl8TSTsZ0khvzSK2LQ0"; String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"; String param = "corpid=" + corpid + "&corpsecret=" + corpsecret; String result = HttpRequestUtil.sendGet(url, param); System.out.println(result); } private static void disableSSLCertificateValidation() { try { TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {} @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {} }}; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HostnameVerifier allHostsValid = (hostname, session) -> true; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } catch (Exception e) { throw new RuntimeException(e); } } } ``` 上述代码实现了对SSL握手过程的完全绕过[^4]。 --- ### 解决方案三:配置Gradle镜像源 如果问题是由于依赖下载失败引起的,可以考虑更换国内镜像源。例如,在项目的`build.gradle`文件中添加阿里云镜像地址: ```groovy buildscript { repositories { google() jcenter() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } } allprojects { repositories { google() jcenter() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } } ``` 这有助于减少因网络不稳定而导致的证书验证失败问题[^3]。 --- ### 总结 - 推荐优先采用**解决方案一**,即手动导入目标站点的SSL证书至JDK信任库。 - 若仅为快速排查问题,可暂时使用**解决方案二**,但在实际部署环境中应避免这种方式。 - 对于依赖管理相关的问题,建议按照**解决方案三**调整Gradle配置。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值