问题描述:Spring Boot项目中使用RestTemplate调用https接口出现以下错误
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
问题原因:Java自带的安全证书不受信任,在代码里面的实现方式为在构建restTemplate时忽略证书,绕开SSL验证,解决代码如下代码如下:
import org.springframework.http.client.SimpleClientHttpRequestFactory; import javax.net.ssl.*; import java.io.IOException; import java.net.HttpURLConnection; import java.security.SecureRandom; import java.security.cert.X509Certificate; /** * 跳过证书验证封装 */ public class SSL extends SimpleClientHttpRequestFactory { @Override protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { if (connection instanceof HttpsURLConnection) { prepareHttpsConnection((HttpsURLConnection) connection); } super.prepareConnection(connection, httpMethod); } private void prepareHttpsConnection(HttpsURLConnection connection) { connection.setHostnameVerifier(new SkipHostnameVerifier()); try { connection.setSSLSocketFactory(createSslSocketFactory()); } catch (Exception ex) { // Ignore } } private SSLSocketFactory createSslSocketFactory() throws Exception { SSLContext context = SSLContext.getInstance("TLS"); context.init(null, new TrustManager[] { new SkipX509TrustManager() }, new SecureRandom()); return context.getSocketFactory(); } private class SkipHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String s, SSLSession sslSession) { return true; } } private static class SkipX509TrustManager implements X509TrustManager { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } } }
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory) { return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory() { SSL factory = new SSL(); factory.setReadTimeout(5000); factory.setConnectTimeout(15000); return factory; } }