We often run into certificate issue while using Rest Template.
RestTemplate can give any of the below error if SSL certificate of the target host is not valid :
PKIX path building failed : sun.security.provider.certpath
-
PKIX path building failed : sun.security.provider.certpath.SunCertPathBuilderException : unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: PKIX path building failed
Reasons for invalid SSL certificate could be any of the below :
Expired certificates.
Self-signed certificates.
Wrong host information in certificates.
Revoked certificates
-
Untrusted root of certificates.
How we deal with it in production and non-production environment ?
In production environment, we usually add the required certificates to our application key-store, which allows us to make the HTTPS request successfully.
In non production environments, while developing an application, we often need to disable ssl certificate validation (self-signed, expired, non trusted root, etc)
as we donβt want to go through the hassle of generating appropriate certificates and managing the key-store for testing purpose.
So, We configure RestTemplate to disable SSL validation (non-prod environment), and thus trust all kind of certificates whether valid or not in Spring Boot RestTemplate and allow http requests to the hosts without throwing exception.
public RestTemplate restTemplate()
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
Note : Avoid SSL Validation for RestTemplate for development environment only.
For production environment, we must do certificate management and SSL verification as disabling SSL verification might lead to security risks.
Top comments (2)
This article does not cover cases when RestTemplate is created by new statement (not autowired, not passed as constructor arg) within external packages.
When the URL is provided at runtime by a user using the UI, how do we install the certificate to the keystore?