I am calling an external API via RestTemplate that requires SSL Certificate. Already the external API provider has provided me with the certificate file (company.crt) and its key file (company.key). While adding the certificate, key and password in Postman, I am able to successfully call the API. But when I am calling using RestTemplate inside a SpringBoot project, even after adding SSLContext, I am receiving an error.
The steps I have followed:
Created a company.p12 store file from company.crt and company.key file using openssl:
openssl pkcs12 -export -name servercert -in company.crt -inkey company.key -out company.p12
Converted company.p12 to company.jks store file using Keytool:
keytool -importkeystore -destkeystore company.jks -srckeystore company.p12 -srcstoretype pkcs12 -alias companycert
Have created the config inside application.properties file as, after placing company.jks inside resource folder of SpringBoot project:
http.client.ssl.trust-store=classpath:company.jks
http.client.ssl.trust-store-password=Password
Then, I have created a configuration for RestTemplate as:
@Value("${http.client.ssl.trust-store}")
private Resource keyStore;
@Value("${http.client.ssl.trust-store-password}")
private String keyStorePassword;
@Bean
RestTemplate restTemplate() throws Exception {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(
keyStore.getURL(),
keyStorePassword.toCharArray()
).build();
SSLConnectionSocketFactory socketFactory =
new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory).build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
Calling an external APIs as:
@Autowired
RestTemplate restTemplate;
@GetMapping("/api")
public Object callAPI() {
final String ENDPOINT = "https://some-api.domain.com:8533/api/key/";
Object response = restTemplate.exchange(ENDPOINT, HttpMethod.GET, request, Object.class);
return response;
}
The error after calling an API via RestTemplate:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target