I'm trying to use new RestClient with client certificate authentication, however I'm getting access denied (however works with curl). My thought process was something along:
- create KeyStore with key, cert and chain
private KeyStore getKeyStore() throws Exception{
var cert = certificateRepository.findByFqdnEqualsIgnoreCase("cert.domain.org").orElseThrow();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
var decPass = aesCypherService.decodeByPassword(cert.getPassword(), iv);
String privateKey = aesCypherService.decodeByPassword(cert.getDataPrivate(), decPass);
var chain = new Certificate[1+cert.getChain().size()];
chain[0] = SSLUtils.getCertificateFromString(aesCypherService.decodeByPassword(cert.getDataPublic(), decPass));
var it = 1;
for(var chainCerts : cert.getChain())
{
chain[it] = SSLUtils.getCertificateFromString(chainCerts.getDataPublic());
it++;
}
keyStore.setKeyEntry("serviceurl.org", SSLUtils.getPrivateKeyFromString(privateKey), generatedPassword.toCharArray(), chain);
return keyStore;
}
- create HttpClient using keystore as its ssl context
private HttpClient clientHttpRequestFactory() {
SSLContext sslContext;
try {
sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(getKeyStore(), generatedPassword.toCharArray())
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
SSLConnectionSocketFactory socketFactory = SSLConnectionSocketFactoryBuilder.create().setSslContext(sslContext).build();
HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(socketFactory)
.build();
return HttpClients.custom()
.setConnectionManager(connectionManager)
.setTargetAuthenticationStrategy(new DefaultAuthenticationStrategy())
.build();
}
- create underlying RestTemplate
@Bean
@Qualifier("customRestTemplate")
public RestTemplate customRestTemplate() {
RestTemplate restTemplate = new RestTemplateBuilder()
.rootUri("https://serviceurl.org")
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(clientHttpRequestFactory()))
.build();
return restTemplate;
}
- create RestClient (via predefined interface)
@Bean
public MyRestClientImpl myRestClientImpl(@Qualifier("customRestTemplate") RestTemplate restTemplate)
{
var rc = RestClient.builder(restTemplate)
.baseUrl("https://serviceurl.org")
.build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(RestClientAdapter.create(rc)).build();
return factory.createClient(MyRestClientImpl.class);
}
Please is there any way to debug this easily? Or is there any mistake in my thought process / code?