场景:
今天有一个功能,spring cloud项目需要调用远程https 接口,使用 RestTemplate,本地测试无异常;部署到测试环境后报证书问题:异常如下:
I/O error on POST request for "https://gateway.xxx.com/yao/user/login": 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

解决办法1:因为是https证书问题,所以配置了信任所有证书,响应正常。
解决办法2:代码方式证书配置
代码如下:
@Bean(name="restTemplateRemote")
public RestTemplate restTemplateRemote() throws Exception {
TrustManager[] trustAllCerts =new TrustManager[] {
new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sslContext =SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
CloseableHttpClient httpClient =HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
HttpComponentsClientHttpRequestFactory customRequestFactory =new HttpComponentsClientHttpRequestFactory();
customRequestFactory.setHttpClient(httpClient);
return new RestTemplate(customRequestFactory);
}
service层代码:
此处因为是调用第三方https接口,并不是nacos注册中心的服务,所以不用@LoadBalanced注解
@Autowired
@Qualifier(value = "restTemplateRemote")
private RestTemplate restTemplate;
接口入参出参均为json格式数据
private String refreshToken(LoginVo vo){
try {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
httpHeaders.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<String> formEntity = new HttpEntity<String>(JSONObject.toJSONString(vo), httpHeaders);
String post = restTemplate.postForObject("https://gateway.xxx.com/yao/user/login", formEntity, String.class);
if (StringUtils.isNotBlank(post)) {
JSONObject jsonObject = JSONObject.parseObject(post);
if (jsonObject.getString("code").endsWith("200")) {
JSONObject data = jsonObject.getJSONObject("data");
String token = data.getString("token");
return token;
}
}
} catch (Exception e) {
log.error("获取token异常:{}", e);
throw new FundException("获取token异常:" + e.getMessage());
}
return null;
}
本文探讨了SpringCloud项目中遇到的HTTPS证书问题,通过配置信任所有证书和代码方式定制SSLContext解决,重点展示了如何在RestTemplate中设置自定义TrustManager。
2391

被折叠的 条评论
为什么被折叠?



