[ACS-4460] configure beans for WebClient.Builder and RestTemplate

This commit is contained in:
kcichonczyk 2023-02-23 17:37:13 +01:00
parent 88b8b851b2
commit 4c77021796

View File

@ -35,6 +35,7 @@ import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@ -58,51 +59,81 @@ import java.security.cert.CertificateException;
@Configuration @Configuration
public class MTLSConfig { public class MTLSConfig {
@Value("${server.ssl.enabled:false}") @Value("${client.ssl.key-store:#{null}}")
boolean sslEnabled;
@Value("${server.ssl.key.store:}")
private Resource keyStoreResource; private Resource keyStoreResource;
@Value("${server.ssl.key.password:}") @Value("${client.ssl.key-store-password:}")
private char[] keyPassword;
@Value("${server.ssl.key.store.password:}")
private char[] keyStorePassword; private char[] keyStorePassword;
@Value("${server.ssl.key.store.type:}") @Value("${client.ssl.key-store-type:}")
private String keyStoreType; private String keyStoreType;
@Value("${server.ssl.trust.store:}") @Value("${client.ssl.trust-store:#{null}}")
private Resource trustStoreResource; private Resource trustStoreResource;
@Value("${server.ssl.trust.store.password:}") @Value("${client.ssl.trust-store-password:}")
private char[] trustStorePassword; private char[] trustStorePassword;
@Value("${server.ssl.trust.store.type:}") @Value("${client.ssl.trust-store-type:}")
private String trustStoreType; private String trustStoreType;
@Bean @Bean()
public WebClient.Builder clientBuilder() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException { @Scope("prototype")
if(sslEnabled) public WebClient.Builder clientBuilder() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException
{
if(isTlsOrMtlsConfigured())
{ {
HttpClient httpClient = getHttpClientWithMTLS(); return createWebClientBuilderWithSslContext();
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient));
} else { } else {
return WebClient.builder(); return WebClient.builder();
} }
} }
private HttpClient getHttpClientWithMTLS() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException { @Bean
KeyManagerFactory keyManagerFactory = initKeyManagerFactory(); public RestTemplate restTemplate() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException
TrustManagerFactory trustManagerFactory = initTrustManagerFactory(); {
if(isTlsOrMtlsConfigured())
{
return createRestTemplateWithSslContext();
} else {
return new RestTemplate();
}
}
SslContext sslContext = SslContextBuilder.forClient() private boolean isTlsOrMtlsConfigured()
.trustManager(trustManagerFactory) {
.keyManager(keyManagerFactory) return isTruststoreConfigured() || isKeystoreConfigured();
.build(); }
return HttpClient.create().secure(p -> p.sslContext(sslContext)); private boolean isTruststoreConfigured()
{
return trustStoreResource != null;
}
private boolean isKeystoreConfigured()
{
return keyStoreResource != null;
}
private WebClient.Builder createWebClientBuilderWithSslContext() throws UnrecoverableKeyException, CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException
{
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
if(isKeystoreConfigured())
{
KeyManagerFactory keyManagerFactory = initKeyManagerFactory();
sslContextBuilder.keyManager(keyManagerFactory);
}
if(isTruststoreConfigured())
{
TrustManagerFactory trustManagerFactory = initTrustManagerFactory();
sslContextBuilder.trustManager(trustManagerFactory);
}
SslContext sslContext = sslContextBuilder.build();
HttpClient httpClient = HttpClient.create().secure(p -> p.sslContext(sslContext));
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient));
} }
private TrustManagerFactory initTrustManagerFactory() throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException private TrustManagerFactory initTrustManagerFactory() throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException
@ -113,10 +144,11 @@ public class MTLSConfig {
return trustManagerFactory; return trustManagerFactory;
} }
private KeyManagerFactory initKeyManagerFactory() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException { private KeyManagerFactory initKeyManagerFactory() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException
{
KeyStore clientKeyStore = getKeyStore(keyStoreType, keyStoreResource, keyStorePassword); KeyStore clientKeyStore = getKeyStore(keyStoreType, keyStoreResource, keyStorePassword);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, keyPassword); keyManagerFactory.init(clientKeyStore, keyStorePassword);
return keyManagerFactory; return keyManagerFactory;
} }
@ -130,25 +162,22 @@ public class MTLSConfig {
return keyStore; return keyStore;
} }
@Bean private RestTemplate createRestTemplateWithSslContext() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException
public RestTemplate restTemplate() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException
{ {
if(sslEnabled) SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
if(isKeystoreConfigured())
{ {
return getRestTemplateWithMTLS(); KeyStore keyStore = getKeyStore(keyStoreType, keyStoreResource, keyStorePassword);
} else { sslContextBuilder.loadKeyMaterial(keyStore, keyStorePassword);
return new RestTemplate();
} }
}
private RestTemplate getRestTemplateWithMTLS() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException if(isTruststoreConfigured())
{ {
KeyStore keyStore = getKeyStore(keyStoreType, keyStoreResource, keyStorePassword); sslContextBuilder.loadTrustMaterial(trustStoreResource.getURL(), trustStorePassword);
SSLContext sslContext = new SSLContextBuilder() }
.loadKeyMaterial(keyStore, keyPassword)
.loadTrustMaterial(trustStoreResource.getURL(), trustStorePassword)
.build();
SSLContext sslContext = sslContextBuilder.build();
SSLConnectionSocketFactory sslContextFactory = new SSLConnectionSocketFactory(sslContext); SSLConnectionSocketFactory sslContextFactory = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslContextFactory).build(); CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslContextFactory).build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);