Add sample for self-signed certificate Mutual-TLS client authentication method

Issue gh-1559
This commit is contained in:
Joe Grandja
2024-04-02 15:38:43 -04:00
parent 31e97c8113
commit 9bd0043cc6
9 changed files with 188 additions and 16 deletions

View File

@@ -43,8 +43,8 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@Configuration(proxyBeanMethods = false)
public class RestTemplateConfig {
@Bean
Supplier<ClientHttpRequestFactory> clientHttpRequestFactory(SslBundles sslBundles) {
@Bean("default-client-http-request-factory")
Supplier<ClientHttpRequestFactory> defaultClientHttpRequestFactory(SslBundles sslBundles) {
return () -> {
SslBundle sslBundle = sslBundles.getBundle("demo-client");
final SSLContext sslContext = sslBundle.createSslContext();
@@ -63,4 +63,23 @@ public class RestTemplateConfig {
};
}
@Bean("self-signed-demo-client-http-request-factory")
Supplier<ClientHttpRequestFactory> selfSignedDemoClientHttpRequestFactory(SslBundles sslBundles) {
return () -> {
SslBundle sslBundle = sslBundles.getBundle("self-signed-demo-client");
final SSLContext sslContext = sslBundle.createSslContext();
final SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.build();
final BasicHttpClientConnectionManager connectionManager =
new BasicHttpClientConnectionManager(socketFactoryRegistry);
final CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
};
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class SecurityConfig {
http
.authorizeHttpRequests(authorize ->
authorize
.requestMatchers("/logged-out").permitAll()
.requestMatchers("/jwks", "/logged-out").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauth2Login ->

View File

@@ -20,6 +20,7 @@ import java.util.function.Supplier;
import sample.authorization.DeviceCodeOAuth2AuthorizedClientProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -52,8 +53,47 @@ import org.springframework.web.reactive.function.client.WebClient;
@Configuration(proxyBeanMethods = false)
public class WebClientConfig {
@Bean
public WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
@Bean("default-client-web-client")
public WebClient defaultClientWebClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
// @formatter:off
return WebClient.builder()
.apply(oauth2Client.oauth2Configuration())
.build();
// @formatter:on
}
@Bean("self-signed-demo-client-web-client")
public WebClient selfSignedDemoClientWebClient(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository,
RestTemplateBuilder restTemplateBuilder,
@Qualifier("self-signed-demo-client-http-request-factory") Supplier<ClientHttpRequestFactory> clientHttpRequestFactory) {
// @formatter:off
RestTemplate restTemplate = restTemplateBuilder
.requestFactory(clientHttpRequestFactory)
.messageConverters(Arrays.asList(
new FormHttpMessageConverter(),
new OAuth2AccessTokenResponseHttpMessageConverter()))
.errorHandler(new OAuth2ErrorResponseErrorHandler())
.build();
// @formatter:on
// @formatter:off
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials(clientCredentials ->
clientCredentials.accessTokenResponseClient(
createClientCredentialsTokenResponseClient(restTemplate)))
.build();
// @formatter:on
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
// @formatter:off
@@ -68,7 +108,7 @@ public class WebClientConfig {
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository,
RestTemplateBuilder restTemplateBuilder,
Supplier<ClientHttpRequestFactory> clientHttpRequestFactory) {
@Qualifier("default-client-http-request-factory") Supplier<ClientHttpRequestFactory> clientHttpRequestFactory) {
// @formatter:off
RestTemplate restTemplate = restTemplateBuilder