Client certificate authentication Spring Boot - RestClient

143 views Asked by At

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:

  1. 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;
    }
  1. 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();
    }
  1. create underlying RestTemplate
@Bean
    @Qualifier("customRestTemplate")
    public RestTemplate customRestTemplate() {
        RestTemplate restTemplate = new RestTemplateBuilder()
                .rootUri("https://serviceurl.org")
                .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(clientHttpRequestFactory()))
                .build();

        return restTemplate;
    }
  1. 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?

0

There are 0 answers