I have a Spring Boot Microservice where I am trying to invoke an external server which exposes an HTTPS REST Endpoint (TLS v1.2). I have been provided the server side certificate in .pem format.
I would like to implement this call using RestTemplate and use the provided certificate and verify the host name during the call.
I have tried to Google this and all the search results are trying to ignore the certificate and host name.
Can I have an example code snippet to implement this properly?
After some digging with different blogs and stackoverflow threads, following worked for me:
Create Rest Template:
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(ResourceUtils.getFile(clientKeyPath)), "".toCharArray());
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(keyStore, null)
.loadTrustMaterial(ResourceUtils.getFile(keystorePath), keystorePassword.toCharArray())
.build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new CustomHostnameVerifier());
HttpClient client = HttpClients
.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(client);
RestTemplate sslRestTemplate = new RestTemplate(requestFactory);
Implementation of CustomHostnameVerifier:
@Component
public class CustomHostnameVerifier implements HostnameVerifier {
@Value("${dns.name}")
private String dnsName;
@Override
public boolean verify(String hostname, SSLSession session) {
return hostname.equals(dnsName);
}
}