背景: 客户端某系统a通过https方式请求另外一个系统b,a系统抛出异常
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://b.***.com/api/openPlatform/***": sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
问题探究:
通过浏览器访问https://b.***.com 页面时候,提示证书是安全的,再进一步查看证书详情,发现证书是Let's Encrypt机构颁发的,按正常来讲,如果证书是绝对安全的(公认受信任的机构颁发的),是不会报上面异常的,所以怀疑是不是,即使浏览器信任上述证书,但是jdk还是不信任的,所以它还是到本地去看,有没有在本地找到受信任的证书,我们第一个解决方案就是 找到这个证书对应的crt,导入到a系统的jdk中,重启后发现不再报错,虽然问题解决,但也未解决内心疑惑,进一步查找资料发现,部分jdk版本和Let's Encrypt证书是不兼容的,我们系统在用的版本恰好是在不兼容范围内的jdk,于是升级了下jdk,升级到8u251,问题解决,以后再也不必因为免费证书3个月到期后客户端频繁的跟着导入证书了。
参考资料:https://letsencrypt.org/docs/certificate-compatibility/