diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java b/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java index 799f2ab..4ee0d2d 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java @@ -16,6 +16,7 @@ package org.springframework.credhub.configuration; +import org.springframework.credhub.core.CredHubOperations; import org.springframework.credhub.core.CredHubProperties; import org.springframework.credhub.core.CredHubTemplate; import org.springframework.credhub.core.ReactiveCredHubOperations; @@ -23,6 +24,8 @@ import org.springframework.credhub.core.ReactiveCredHubTemplate; import org.springframework.credhub.support.ClientOptions; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.reactive.ClientHttpConnector; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; @@ -40,7 +43,7 @@ public class CredHubTemplateFactory { * Create a {@link CredHubTemplate} for interaction with a CredHub server. * * @param credHubProperties connection properties - * @param clientOptions connection options + * @param clientOptions connection options * @return a {@code CredHubTemplate} */ public CredHubTemplate credHubTemplate(CredHubProperties credHubProperties, @@ -52,10 +55,10 @@ public class CredHubTemplateFactory { * Create a {@link CredHubTemplate} for interaction with a CredHub server * using OAuth2 for authentication. * - * @param credHubProperties connection properties - * @param clientOptions connection options + * @param credHubProperties connection properties + * @param clientOptions connection options * @param clientRegistrationRepository a repository of OAuth2 client registrations - * @param authorizedClientRepository a repository of authorized OAuth2 clients + * @param authorizedClientRepository a repository of authorized OAuth2 clients * @return a {@code CredHubTemplate} */ public CredHubTemplate credHubTemplate(CredHubProperties credHubProperties, @@ -66,11 +69,28 @@ public class CredHubTemplateFactory { clientRegistrationRepository, authorizedClientRepository); } + /** + * Create a {@link CredHubTemplate} for interaction with a CredHub server + * using OAuth2 for authentication. + * + * @param credHubProperties connection properties + * @param clientOptions connection options + * @param clientRegistrationRepository a repository of OAuth2 client registrations + * @param clientManager an OAuth2 authorization client manager + * @return a {@code CredHubTemplate} + */ + public CredHubOperations credHubTemplate(CredHubProperties credHubProperties, ClientOptions clientOptions, + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientManager clientManager) { + return new CredHubTemplate(credHubProperties, clientHttpRequestFactory(clientOptions), + clientRegistrationRepository, clientManager); + } + /** * Create a {@link ReactiveCredHubTemplate} for interaction with a CredHub server. * * @param credHubProperties connection properties - * @param clientOptions connection options + * @param clientOptions connection options * @return a {@code ReactiveCredHubTemplate} */ public ReactiveCredHubTemplate reactiveCredHubTemplate(CredHubProperties credHubProperties, @@ -82,10 +102,10 @@ public class CredHubTemplateFactory { * Create a {@link ReactiveCredHubTemplate} for interaction with a CredHub server * using OAuth2 for authentication. * - * @param credHubProperties connection properties - * @param clientOptions connection options + * @param credHubProperties connection properties + * @param clientOptions connection options * @param clientRegistrationRepository a repository of OAuth2 client registrations - * @param authorizedClientRepository a repository of OAuth2 client authorizations + * @param authorizedClientRepository a repository of OAuth2 client authorizations * @return a {@code ReactiveCredHubTemplate} */ public ReactiveCredHubOperations reactiveCredHubTemplate(CredHubProperties credHubProperties, @@ -96,6 +116,21 @@ public class CredHubTemplateFactory { clientRegistrationRepository, authorizedClientRepository); } + /** + * Create a {@link ReactiveCredHubTemplate} for interaction with a CredHub server + * using OAuth2 for authentication. + * + * @param credHubProperties connection properties + * @param clientOptions connection options + * @param clientManager an OAuth2 authorization client manager + * @return a {@code ReactiveCredHubTemplate} + */ + public ReactiveCredHubOperations reactiveCredHubTemplate(CredHubProperties credHubProperties, + ClientOptions clientOptions, + ReactiveOAuth2AuthorizedClientManager clientManager) { + return new ReactiveCredHubTemplate(credHubProperties, clientHttpConnector(clientOptions), clientManager); + } + /** * Create a {@link ClientHttpRequestFactory}. * diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubRestTemplateFactory.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubRestTemplateFactory.java index 8fbe4b2..affd543 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubRestTemplateFactory.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubRestTemplateFactory.java @@ -92,11 +92,31 @@ class CredHubRestTemplateFactory { RestTemplate restTemplate = new RestTemplate(); configureRestTemplate(restTemplate, properties.getUrl(), clientHttpRequestFactory); - configureOAuth2(restTemplate, - clientHttpRequestFactory, - properties.getOauth2().getRegistrationId(), - clientRegistrationRepository, - authorizedClientRepository); + configureOAuth2(restTemplate, properties.getOauth2().getRegistrationId(), clientRegistrationRepository, + buildClientManager(clientRegistrationRepository, authorizedClientRepository, clientHttpRequestFactory)); + + return restTemplate; + } + + /** + * Create a {@link RestTemplate} configured for communication with a CredHub server. + * + * @param properties CredHub connection properties + * @param clientHttpRequestFactory the {@link ClientHttpRequestFactory} to use when + * creating new connections + * @param clientRegistrationRepository a repository of OAuth2 client registrations + * @param clientManager an OAuth2 authorization client manager + * @return a configured {@link RestTemplate} + */ + public static RestTemplate createRestTemplate(CredHubProperties properties, + ClientHttpRequestFactory clientHttpRequestFactory, + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientManager clientManager) { + RestTemplate restTemplate = new RestTemplate(); + + configureRestTemplate(restTemplate, properties.getUrl(), clientHttpRequestFactory); + configureOAuth2(restTemplate, properties.getOauth2().getRegistrationId(), clientRegistrationRepository, + clientManager); return restTemplate; } @@ -124,29 +144,31 @@ class CredHubRestTemplateFactory { * Configure OAuth2 features of a {@link RestTemplate}. * * @param restTemplate an existing {@link RestTemplate} to configure - * @param clientHttpRequestFactory the {@link ClientHttpRequestFactory} to use when - * creating new connections * @param clientId the OAuth2 client ID for authentication * @param clientRegistrationRepository a repository of OAuth2 client registrations - * @param authorizedClientRepository a repository of authorized OAuth2 clients + * @param clientManager an OAuth2 authorization client manager */ private static void configureOAuth2(RestTemplate restTemplate, - ClientHttpRequestFactory clientHttpRequestFactory, String clientId, ClientRegistrationRepository clientRegistrationRepository, - OAuth2AuthorizedClientRepository authorizedClientRepository) { - ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId(clientId); + OAuth2AuthorizedClientManager clientManager) { + ClientRegistration clientRegistration = getClientRegistration(clientRegistrationRepository, clientId); + + restTemplate.getInterceptors() + .add(new CredHubOAuth2RequestInterceptor(clientRegistration, clientManager)); + } + + private static ClientRegistration getClientRegistration(ClientRegistrationRepository clientRegistrationRepository, + String clientId) { + ClientRegistration clientRegistration = clientRegistrationRepository + .findByRegistrationId(clientId); if (clientRegistration == null) { throw new IllegalStateException("The CredHub OAuth2 client registration ID '" + clientId + "' is not a valid Spring Security OAuth2 client registration"); } - OAuth2AuthorizedClientManager clientManager = - buildClientManager(clientRegistrationRepository, authorizedClientRepository, clientHttpRequestFactory); - - restTemplate.getInterceptors() - .add(new CredHubOAuth2RequestInterceptor(clientRegistration, clientManager)); + return clientRegistration; } private static OAuth2AuthorizedClientManager buildClientManager( diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java index 604aac7..47f7527 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java @@ -29,6 +29,7 @@ import org.springframework.credhub.core.permission.CredHubPermissionTemplate; import org.springframework.credhub.core.permissionV2.CredHubPermissionV2Operations; import org.springframework.credhub.core.permissionV2.CredHubPermissionV2Template; import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.util.Assert; @@ -97,6 +98,28 @@ public class CredHubTemplate implements CredHubOperations { this.usingOAuth2 = true; } + /** + * Create a new {@link CredHubTemplate} using the provided connection properties, + * {@link ClientHttpRequestFactory}, and OAuth2 support. + * + * @param properties CredHub connection properties; must not be {@literal null} + * @param clientHttpRequestFactory the {@link ClientHttpRequestFactory} to use when + * creating new connections + * @param clientRegistrationRepository a repository of OAuth2 client registrations + * @param clientManager an OAuth2 authorization client manager + */ + public CredHubTemplate(CredHubProperties properties, ClientHttpRequestFactory clientHttpRequestFactory, + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientManager clientManager) { + Assert.notNull(properties, "properties must not be null"); + Assert.notNull(clientHttpRequestFactory, "clientHttpRequestFactory must not be null"); + Assert.notNull(clientManager, "clientManager must not be null"); + + this.restTemplate = CredHubRestTemplateFactory.createRestTemplate(properties, + clientHttpRequestFactory, clientRegistrationRepository, clientManager); + this.usingOAuth2 = true; + } + /** * Get the operations for saving, retrieving, and deleting credentials. * diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/ReactiveCredHubTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/ReactiveCredHubTemplate.java index 81da287..0c397fa 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/ReactiveCredHubTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/ReactiveCredHubTemplate.java @@ -101,15 +101,15 @@ public class ReactiveCredHubTemplate implements ReactiveCredHubOperations { this.usingOAuth2 = true; } - /** - * Create a new {@link ReactiveCredHubTemplate} using the provided base URI and - * {@link ClientHttpRequestFactory}. - * - * @param credHubProperties connection properties for the CredHub server - * @param clientHttpConnector the {@link ClientHttpConnector} to use when - * creating new connections - * @param clientManager an OAuth2 authorization client manager - */ + /** + * Create a new {@link ReactiveCredHubTemplate} using the provided base URI and + * {@link ClientHttpRequestFactory}. + * + * @param credHubProperties connection properties for the CredHub server + * @param clientHttpConnector the {@link ClientHttpConnector} to use when + * creating new connections + * @param clientManager an OAuth2 authorization client manager + */ public ReactiveCredHubTemplate(CredHubProperties credHubProperties, ClientHttpConnector clientHttpConnector, ReactiveOAuth2AuthorizedClientManager clientManager) { Assert.notNull(credHubProperties, "credHubProperties must not be null"); diff --git a/spring-credhub-reactive-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java b/spring-credhub-reactive-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java index dd6c76f..7e5c130 100644 --- a/spring-credhub-reactive-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java +++ b/spring-credhub-reactive-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java @@ -18,10 +18,30 @@ package org.springframework.credhub.integration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider; +import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; @SpringBootApplication -public class TestApplication { +public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } + + @Configuration(proxyBeanMethods = false) + static class ClientManagerConfiguration { + @Bean + AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager reactiveClientManager( + ReactiveClientRegistrationRepository clientRegistrationRepository, + ReactiveOAuth2AuthorizedClientService authorizedClientService) { + AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager clientManager = + new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager( + clientRegistrationRepository, authorizedClientService); + clientManager.setAuthorizedClientProvider(new ClientCredentialsReactiveOAuth2AuthorizedClientProvider()); + return clientManager; + } + } } diff --git a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java index 0ea2652..9c7b15e 100644 --- a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java +++ b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java @@ -32,7 +32,7 @@ import org.springframework.credhub.support.ClientOptions; * @author Scott Frederick * @author Daniel Lavoie */ -@Configuration +@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties public class CredHubAutoConfiguration { /** diff --git a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfiguration.java b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfiguration.java index 2d2ecab..f144651 100644 --- a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfiguration.java +++ b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfiguration.java @@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.oauth2.client.ClientsConfiguredCondition; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter; @@ -48,10 +49,11 @@ import java.util.List; * * @author Scott Frederick */ -@Configuration +@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(OAuth2ClientProperties.class) @AutoConfigureAfter({OAuth2ClientAutoConfiguration.class, ReactiveOAuth2ClientAutoConfiguration.class}) @ConditionalOnClass(name = "org.springframework.security.oauth2.client.registration.ClientRegistration") +@ConditionalOnProperty("spring.credhub.oauth2.registration-id") @Conditional(ClientsConfiguredCondition.class) public class CredHubOAuth2AutoConfiguration { diff --git a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfiguration.java b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfiguration.java index 66a96ac..82f3bf8 100644 --- a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfiguration.java +++ b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfiguration.java @@ -16,106 +16,28 @@ package org.springframework.credhub.autoconfig; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration; import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.credhub.configuration.CredHubTemplateFactory; -import org.springframework.credhub.core.CredHubOperations; +import org.springframework.context.annotation.Import; import org.springframework.credhub.core.CredHubProperties; import org.springframework.credhub.core.CredHubTemplate; -import org.springframework.credhub.core.ReactiveCredHubOperations; -import org.springframework.credhub.core.ReactiveCredHubTemplate; -import org.springframework.credhub.support.ClientOptions; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; -import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; -import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link CredHubTemplate}. * - * @author Daniel Lavoie * @author Scott Frederick */ -@Configuration +@Configuration(proxyBeanMethods = false) @AutoConfigureAfter({CredHubAutoConfiguration.class, CredHubOAuth2AutoConfiguration.class, OAuth2ClientAutoConfiguration.class, ReactiveOAuth2ClientAutoConfiguration.class}) @ConditionalOnBean(CredHubProperties.class) +@Import({CredHubTemplateConfiguration.class, ReactiveCredHubTemplateConfiguration.class}) public class CredHubTemplateAutoConfiguration { - private final CredHubTemplateFactory credHubTemplateFactory = new CredHubTemplateFactory(); - - /** - * Create the {@link CredHubTemplate} that the application will use to interact - * with CredHub. - * - * @param credHubProperties {@link CredHubProperties} for CredHub - * @param clientOptions client connection options - * @param clientRegistrationRepository a repository of OAuth2 client registrations - * @param authorizedClientRepository a repository of authorized OAuth2 clients - * @return the {@link CredHubOperations} bean - */ - @Bean - @ConditionalOnMissingBean - @ConditionalOnClass(name = "javax.servlet.http.HttpServletRequest") - public CredHubOperations credHubTemplate( - CredHubProperties credHubProperties, ClientOptions clientOptions, - @Autowired(required = false) ClientRegistrationRepository clientRegistrationRepository, - @Autowired(required = false) OAuth2AuthorizedClientRepository authorizedClientRepository) { - - if (credHubProperties.getOauth2() == null || credHubProperties.getOauth2().getRegistrationId() == null) { - return credHubTemplateFactory.credHubTemplate(credHubProperties, clientOptions); - } - - if (clientRegistrationRepository == null || authorizedClientRepository == null) { - throw misconfiguredException(); - } - - return credHubTemplateFactory.credHubTemplate(credHubProperties, clientOptions, - clientRegistrationRepository, authorizedClientRepository); - } - - /** - * Create the {@link ReactiveCredHubTemplate} that the application will use to interact - * with CredHub. - * - * @param credHubProperties {@link CredHubProperties} for CredHub - * @param clientOptions client connection options - * @param clientRegistrationRepository a repository of OAuth2 client registrations - * @param authorizedClientRepository a repository of OAuth2 authorized clients - * @return the {@link CredHubTemplate} bean - */ - @Bean - @ConditionalOnMissingBean - @ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient") - public ReactiveCredHubOperations reactiveCredHubTemplate( - CredHubProperties credHubProperties, ClientOptions clientOptions, - @Autowired(required = false) ReactiveClientRegistrationRepository clientRegistrationRepository, - @Autowired(required = false) ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { - - if (credHubProperties.getOauth2() == null || credHubProperties.getOauth2().getRegistrationId() == null) { - return credHubTemplateFactory.reactiveCredHubTemplate(credHubProperties, clientOptions); - } - - if (clientRegistrationRepository == null || authorizedClientRepository == null) { - throw misconfiguredException(); - } - return credHubTemplateFactory.reactiveCredHubTemplate(credHubProperties, clientOptions, - clientRegistrationRepository, authorizedClientRepository); - } - - private IllegalArgumentException misconfiguredException() { - return new IllegalArgumentException("A CredHub OAuth2 client registration is configured " + - "but Spring Security is not available or the Spring Security OAuth2 " + - "client registration is misconfigured"); - } } diff --git a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateConfiguration.java b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateConfiguration.java new file mode 100644 index 0000000..c6f4ebe --- /dev/null +++ b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubTemplateConfiguration.java @@ -0,0 +1,124 @@ +/* + * Copyright 2016-2017 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.credhub.autoconfig; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.credhub.autoconfig.CredHubTemplateConfiguration.CredHubTemplateBaseConfiguration; +import org.springframework.credhub.autoconfig.CredHubTemplateConfiguration.CredHubTemplateOAuth2ClientConfiguration; +import org.springframework.credhub.autoconfig.CredHubTemplateConfiguration.CredHubTemplateOAuth2Configuration; +import org.springframework.credhub.configuration.CredHubTemplateFactory; +import org.springframework.credhub.core.CredHubOperations; +import org.springframework.credhub.core.CredHubProperties; +import org.springframework.credhub.core.CredHubTemplate; +import org.springframework.credhub.support.ClientOptions; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; + +/** + * Configuration for {@link CredHubTemplate}. + * + * @author Daniel Lavoie + * @author Scott Frederick + */ +@Import({CredHubTemplateBaseConfiguration.class, + CredHubTemplateOAuth2Configuration.class, + CredHubTemplateOAuth2ClientConfiguration.class}) +public class CredHubTemplateConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "javax.servlet.http.HttpServletRequest") + @ConditionalOnProperty(prefix = "spring.credhub.oauth2", name = "registration-id", + havingValue = "false", matchIfMissing = true) + static class CredHubTemplateBaseConfiguration { + /** + * Create the {@link CredHubTemplate} that the application will use to interact + * with CredHub. + * + * @param credHubProperties {@link CredHubProperties} for CredHub + * @param clientOptions client connection options + * @return the {@link CredHubOperations} bean + */ + @Bean + @ConditionalOnMissingBean + public CredHubOperations credHubTemplate(CredHubProperties credHubProperties, ClientOptions clientOptions) { + + return new CredHubTemplateFactory().credHubTemplate(credHubProperties, clientOptions); + } + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "javax.servlet.http.HttpServletRequest") + @ConditionalOnProperty(prefix = "spring.credhub.oauth2", name = "registration-id") + @ConditionalOnMissingBean(OAuth2AuthorizedClientManager.class) + static class CredHubTemplateOAuth2Configuration { + /** + * Create the {@link CredHubTemplate} that the application will use to interact + * with CredHub. + * + * @param credHubProperties {@link CredHubProperties} for CredHub + * @param clientOptions client connection options + * @param clientRegistrationRepository a repository of OAuth2 client registrations + * @param authorizedClientRepository a repository of authorized OAuth2 clients + * @return the {@link CredHubOperations} bean + */ + @Bean + @ConditionalOnMissingBean + public CredHubOperations credHubTemplate( + CredHubProperties credHubProperties, ClientOptions clientOptions, + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientRepository authorizedClientRepository) { + + return new CredHubTemplateFactory().credHubTemplate(credHubProperties, clientOptions, + clientRegistrationRepository, authorizedClientRepository); + } + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "javax.servlet.http.HttpServletRequest") + @ConditionalOnProperty(prefix = "spring.credhub.oauth2", name = "registration-id") + @ConditionalOnBean(OAuth2AuthorizedClientManager.class) + static class CredHubTemplateOAuth2ClientConfiguration { + /** + * Create the {@link CredHubTemplate} that the application will use to interact + * with CredHub. + * + * @param credHubProperties {@link CredHubProperties} for CredHub + * @param clientOptions client connection options + * @param clientRegistrationRepository a repository of OAuth2 client registrations + * @param clientManager an OAuth2 authorization client manager + * @return the {@link CredHubTemplate} bean + */ + @Bean + @ConditionalOnMissingBean + public CredHubOperations credHubTemplate( + CredHubProperties credHubProperties, ClientOptions clientOptions, + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientManager clientManager) { + + return new CredHubTemplateFactory().credHubTemplate(credHubProperties, clientOptions, + clientRegistrationRepository, clientManager); + } + } + +} diff --git a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/ReactiveCredHubTemplateConfiguration.java b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/ReactiveCredHubTemplateConfiguration.java new file mode 100644 index 0000000..f5ca152 --- /dev/null +++ b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/ReactiveCredHubTemplateConfiguration.java @@ -0,0 +1,122 @@ +/* + * Copyright 2016-2017 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.credhub.autoconfig; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.credhub.autoconfig.ReactiveCredHubTemplateConfiguration.ReactiveCredHubTemplateBaseConfiguration; +import org.springframework.credhub.autoconfig.ReactiveCredHubTemplateConfiguration.ReactiveCredHubTemplateOAuth2ClientConfiguration; +import org.springframework.credhub.autoconfig.ReactiveCredHubTemplateConfiguration.ReactiveCredHubTemplateOAuth2Configuration; +import org.springframework.credhub.configuration.CredHubTemplateFactory; +import org.springframework.credhub.core.CredHubProperties; +import org.springframework.credhub.core.CredHubTemplate; +import org.springframework.credhub.core.ReactiveCredHubOperations; +import org.springframework.credhub.core.ReactiveCredHubTemplate; +import org.springframework.credhub.support.ClientOptions; +import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; + +/** + * Configuration for {@link ReactiveCredHubTemplate}. + * + * @author Scott Frederick + */ +@Import({ReactiveCredHubTemplateBaseConfiguration.class, + ReactiveCredHubTemplateOAuth2Configuration.class, + ReactiveCredHubTemplateOAuth2ClientConfiguration.class}) +public class ReactiveCredHubTemplateConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient") + @ConditionalOnProperty(prefix = "spring.credhub.oauth2", name = "registration-id", havingValue = "false", matchIfMissing = true) + static class ReactiveCredHubTemplateBaseConfiguration { + /** + * Create the {@link ReactiveCredHubTemplate} that the application will use to interact + * with CredHub. + * + * @param credHubProperties {@link CredHubProperties} for CredHub + * @param clientOptions client connection options + * @return the {@link CredHubTemplate} bean + */ + @Bean + @ConditionalOnMissingBean + public ReactiveCredHubOperations reactiveCredHubTemplate(CredHubProperties credHubProperties, + ClientOptions clientOptions) { + + return new CredHubTemplateFactory().reactiveCredHubTemplate(credHubProperties, clientOptions); + } + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = {"org.springframework.web.reactive.function.client.WebClient"}) + @ConditionalOnProperty(prefix = "spring.credhub.oauth2", name = "registration-id") + @ConditionalOnMissingBean(ReactiveOAuth2AuthorizedClientManager.class) + static class ReactiveCredHubTemplateOAuth2Configuration { + /** + * Create the {@link ReactiveCredHubTemplate} that the application will use to interact + * with CredHub. + * + * @param credHubProperties {@link CredHubProperties} for CredHub + * @param clientOptions client connection options + * @param clientRegistrationRepository a repository of OAuth2 client registrations + * @param authorizedClientRepository a repository of OAuth2 authorized clients + * @return the {@link CredHubTemplate} bean + */ + @Bean + @ConditionalOnMissingBean + public ReactiveCredHubOperations reactiveCredHubTemplate( + CredHubProperties credHubProperties, ClientOptions clientOptions, + ReactiveClientRegistrationRepository clientRegistrationRepository, + ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { + + return new CredHubTemplateFactory().reactiveCredHubTemplate(credHubProperties, clientOptions, + clientRegistrationRepository, authorizedClientRepository); + } + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient") + @ConditionalOnProperty(prefix = "spring.credhub.oauth2", name = "registration-id") + @ConditionalOnBean(ReactiveOAuth2AuthorizedClientManager.class) + static class ReactiveCredHubTemplateOAuth2ClientConfiguration { + /** + * Create the {@link ReactiveCredHubTemplate} that the application will use to interact + * with CredHub. + * + * @param credHubProperties {@link CredHubProperties} for CredHub + * @param clientOptions client connection options + * @param clientManager an OAuth2 authorization client manager + * @return the {@link CredHubTemplate} bean + */ + @Bean + @ConditionalOnMissingBean + public ReactiveCredHubOperations reactiveCredHubTemplate( + CredHubProperties credHubProperties, ClientOptions clientOptions, + ReactiveOAuth2AuthorizedClientManager clientManager) { + + return new CredHubTemplateFactory().reactiveCredHubTemplate(credHubProperties, clientOptions, + clientManager); + } + } + +} diff --git a/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfigurationTests.java b/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfigurationTests.java index 0cffac4..c5ba74d 100644 --- a/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfigurationTests.java +++ b/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubOAuth2AutoConfigurationTests.java @@ -37,6 +37,8 @@ public class CredHubOAuth2AutoConfigurationTests { }; private final String[] oAuth2ClientProperties = { + "spring.credhub.oauth2.registration-id=test-client", + "spring.security.oauth2.client.registration.credhub-client.provider=uaa", "spring.security.oauth2.client.registration.credhub-client.client-id=test-client", "spring.security.oauth2.client.registration.credhub-client.client-secret=test-secret", diff --git a/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfigurationTests.java b/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfigurationTests.java index 3bbbadd..a2b1690 100644 --- a/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfigurationTests.java +++ b/spring-credhub-starter/src/test/java/org/springframework/credhub/autoconfig/CredHubTemplateAutoConfigurationTests.java @@ -16,13 +16,38 @@ package org.springframework.credhub.autoconfig; +import java.util.ArrayList; +import java.util.List; + import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener; +import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; +import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter; import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration; +import org.springframework.boot.logging.LogLevel; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.credhub.core.CredHubTemplate; import org.springframework.credhub.core.ReactiveCredHubTemplate; +import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; +import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; @@ -32,6 +57,14 @@ public class CredHubTemplateAutoConfigurationTests { private static final FilteredClassLoader SPRING_SECURITY_FILTERED_CLASS_LOADER = new FilteredClassLoader("org.springframework.security.oauth2.client"); + private static final FilteredClassLoader SERVLET_AND_SECURITY_FILTERED_CLASS_LOADER = + new FilteredClassLoader("javax.servlet.http.HttpServletRequest", + "org.springframework.security.oauth2.client"); + + private static final FilteredClassLoader WEB_CLIENT_AND_SECURITY_FILTERED_CLASS_LOADER = + new FilteredClassLoader("org.springframework.web.reactive.function.client", + "org.springframework.security.oauth2.client"); + private final ApplicationContextRunner context = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( ReactiveOAuth2ClientAutoConfiguration.class, @@ -39,16 +72,12 @@ public class CredHubTemplateAutoConfigurationTests { CredHubOAuth2AutoConfiguration.class, CredHubTemplateAutoConfiguration.class )) - .withPropertyValues( - "debug=true" - ); + .withInitializer(new ConditionEvaluationReportLoggingListener(LogLevel.INFO)); @Test public void credHubTemplatesConfigured() { context - .withPropertyValues( - "spring.credhub.url=https://localhost" - ) + .withPropertyValues("spring.credhub.url=https://localhost") .withClassLoader(SPRING_SECURITY_FILTERED_CLASS_LOADER) .run(context -> { assertThat(context).hasSingleBean(CredHubTemplate.class); @@ -61,12 +90,25 @@ public class CredHubTemplateAutoConfigurationTests { }); } + @Test + public void credHubTemplatesConfiguredWithSpringSecurityWithoutClientId() { + context + .withPropertyValues("spring.credhub.url=https://localhost") + .run(context -> { + assertThat(context).hasSingleBean(CredHubTemplate.class); + CredHubTemplate credHubTemplate = context.getBean(CredHubTemplate.class); + assertThat(credHubTemplate.isUsingOAuth2()).isFalse(); + + assertThat(context).hasSingleBean(ReactiveCredHubTemplate.class); + ReactiveCredHubTemplate reactiveCredHubTemplate = context.getBean(ReactiveCredHubTemplate.class); + assertThat(reactiveCredHubTemplate.isUsingOAuth2()).isFalse(); + }); + } + @Test public void reactiveCredHubTemplateNotConfiguredWithoutWebClient() { context - .withPropertyValues( - "spring.credhub.url=https://localhost" - ) + .withPropertyValues("spring.credhub.url=https://localhost") .withClassLoader(new FilteredClassLoader(WebClient.class)) .run(context -> { assertThat(context).hasSingleBean(CredHubTemplate.class); @@ -92,47 +134,23 @@ public class CredHubTemplateAutoConfigurationTests { ) .run(context -> { assertThat(context).hasSingleBean(CredHubTemplate.class); + assertThat(context).hasSingleBean(ClientRegistrationRepository.class); + assertThat(context).hasSingleBean(OAuth2AuthorizedClientRepository.class); + assertThat(context).doesNotHaveBean(OAuth2AuthorizedClientManager.class); CredHubTemplate credHubTemplate = context.getBean(CredHubTemplate.class); assertThat(credHubTemplate.isUsingOAuth2()).isTrue(); assertThat(context).hasSingleBean(ReactiveCredHubTemplate.class); + assertThat(context).hasSingleBean(ReactiveClientRegistrationRepository.class); + assertThat(context).hasSingleBean(ServerOAuth2AuthorizedClientRepository.class); + assertThat(context).doesNotHaveBean(ReactiveOAuth2AuthorizedClientManager.class); ReactiveCredHubTemplate reactiveCredHubTemplate = context.getBean(ReactiveCredHubTemplate.class); assertThat(reactiveCredHubTemplate.isUsingOAuth2()).isTrue(); }); } @Test - public void credHubTemplatesNotConfiguredWithInvalidClientRegistration() { - context - .withPropertyValues( - "spring.credhub.url=https://localhost", - "spring.credhub.oauth2.registration-id=invalid-credhub-client", - - "spring.security.oauth2.client.registration.credhub-client.provider=uaa", - "spring.security.oauth2.client.registration.credhub-client.client-id=test-client", - "spring.security.oauth2.client.registration.credhub-client.client-secret=test-secret", - "spring.security.oauth2.client.registration.credhub-client.authorization-grant-type=client_credentials", - "spring.security.oauth2.client.provider.uaa.token-uri=https://example.com/uaa/oauth/token" - ) - .run(context -> assertThat(context) - .getFailure() - .hasMessageContaining("The CredHub OAuth2 client registration ID 'invalid-credhub-client' is not a valid")); - } - - @Test - public void credHubTemplatesNotConfiguredWithMissingClientRegistration() { - context - .withPropertyValues( - "spring.credhub.url=https://localhost", - "spring.credhub.oauth2.registration-id=credhub-client" - ) - .run(context -> assertThat(context) - .getFailure() - .hasMessageContaining("A CredHub OAuth2 client registration is configured but")); - } - - @Test - public void credHubTemplatesNotConfiguredWithOAuth2ButMissingSpringSecurity() { + public void credHubTemplatesConfiguredWithOAuth2AndCustomClientManager() { context .withPropertyValues( "spring.credhub.url=https://localhost", @@ -144,7 +162,132 @@ public class CredHubTemplateAutoConfigurationTests { "spring.security.oauth2.client.registration.credhub-client.authorization-grant-type=client_credentials", "spring.security.oauth2.client.provider.uaa.token-uri=https://example.com/uaa/oauth/token" ) - .withClassLoader(SPRING_SECURITY_FILTERED_CLASS_LOADER) + .withUserConfiguration(ClientManagerConfiguration.class) + .run(context -> { + assertThat(context).hasSingleBean(CredHubTemplate.class); + assertThat(context).hasSingleBean(ClientRegistrationRepository.class); + assertThat(context).hasSingleBean(OAuth2AuthorizedClientRepository.class); + assertThat(context).hasSingleBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class); + CredHubTemplate credHubTemplate = context.getBean(CredHubTemplate.class); + assertThat(credHubTemplate.isUsingOAuth2()).isTrue(); + + assertThat(context).hasSingleBean(ReactiveCredHubTemplate.class); + assertThat(context).hasSingleBean(ReactiveClientRegistrationRepository.class); + assertThat(context).hasSingleBean(ServerOAuth2AuthorizedClientRepository.class); + assertThat(context).hasSingleBean(AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager.class); + ReactiveCredHubTemplate reactiveCredHubTemplate = context.getBean(ReactiveCredHubTemplate.class); + assertThat(reactiveCredHubTemplate.isUsingOAuth2()).isTrue(); + }); + } + + @Test + public void credHubTemplatesNotConfiguredWithInvalidClientRegistration() { + context + .withPropertyValues( + "spring.credhub.url=https://localhost", + "spring.credhub.oauth2.registration-id=invalid-client", + + "spring.security.oauth2.client.registration.credhub-client.provider=uaa", + "spring.security.oauth2.client.registration.credhub-client.client-id=test-client", + "spring.security.oauth2.client.registration.credhub-client.client-secret=test-secret", + "spring.security.oauth2.client.registration.credhub-client.authorization-grant-type=client_credentials", + "spring.security.oauth2.client.provider.uaa.token-uri=https://example.com/uaa/oauth/token" + ) + .run(context -> assertThat(context) + .getFailure() + .hasMessageContaining("The CredHub OAuth2 client registration ID 'invalid-client' is not a valid")); + } + + @Test + public void credHubTemplateNotConfiguredWithMissingClientRegistration() { + context + .withClassLoader(WEB_CLIENT_AND_SECURITY_FILTERED_CLASS_LOADER) + .withPropertyValues( + "spring.credhub.url=https://localhost", + "spring.credhub.oauth2.registration-id=credhub-client" + ) + .run(context -> assertThat(context) + .getFailure() + .hasMessageMatching(noSuchBeanExceptionMessage("ClientRegistrationRepository"))); + } + + @Test + public void reactiveCredHubTemplateNotConfiguredWithMissingClientRegistration() { + context + .withClassLoader(SERVLET_AND_SECURITY_FILTERED_CLASS_LOADER) + .withPropertyValues( + "spring.credhub.url=https://localhost", + "spring.credhub.oauth2.registration-id=credhub-client" + ) + .run(context -> assertThat(context) + .getFailure() + .hasMessageMatching(noSuchBeanExceptionMessage("ReactiveClientRegistrationRepository"))); + } + + @Test + public void credHubTemplateNotConfiguredWithOAuth2ButMissingSpringSecurity() { + context + .withClassLoader(WEB_CLIENT_AND_SECURITY_FILTERED_CLASS_LOADER) + .withPropertyValues( + "spring.credhub.url=https://localhost", + "spring.credhub.oauth2.registration-id=credhub-client", + + "spring.security.oauth2.client.registration.credhub-client.provider=uaa", + "spring.security.oauth2.client.registration.credhub-client.client-id=test-client", + "spring.security.oauth2.client.registration.credhub-client.client-secret=test-secret", + "spring.security.oauth2.client.registration.credhub-client.authorization-grant-type=client_credentials", + "spring.security.oauth2.client.provider.uaa.token-uri=https://example.com/uaa/oauth/token" + ) .run(context -> assertThat(context).hasFailed()); } + + @Test + public void reactiveCredHubTemplateNotConfiguredWithOAuth2ButMissingSpringSecurity() { + context + .withClassLoader(SERVLET_AND_SECURITY_FILTERED_CLASS_LOADER) + .withPropertyValues( + "spring.credhub.url=https://localhost", + "spring.credhub.oauth2.registration-id=credhub-client", + + "spring.security.oauth2.client.registration.credhub-client.provider=uaa", + "spring.security.oauth2.client.registration.credhub-client.client-id=test-client", + "spring.security.oauth2.client.registration.credhub-client.client-secret=test-secret", + "spring.security.oauth2.client.registration.credhub-client.authorization-grant-type=client_credentials", + "spring.security.oauth2.client.provider.uaa.token-uri=https://example.com/uaa/oauth/token" + ) + .run(context -> assertThat(context).hasFailed()); + } + + @Configuration(proxyBeanMethods = false) + static class ClientManagerConfiguration { + @Bean + AuthorizedClientServiceOAuth2AuthorizedClientManager clientManager(OAuth2ClientProperties properties) { + List registrations = new ArrayList<>( + OAuth2ClientPropertiesRegistrationAdapter + .getClientRegistrations(properties).values()); + ClientRegistrationRepository clientRegistrationRepository = + new InMemoryClientRegistrationRepository(registrations); + OAuth2AuthorizedClientService authorizedClientService = + new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository); + return new AuthorizedClientServiceOAuth2AuthorizedClientManager( + clientRegistrationRepository, authorizedClientService); + } + + @Bean + AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager reactiveClientManager(OAuth2ClientProperties properties) { + List registrations = new ArrayList<>( + OAuth2ClientPropertiesRegistrationAdapter + .getClientRegistrations(properties).values()); + ReactiveClientRegistrationRepository clientRegistrationRepository = + new InMemoryReactiveClientRegistrationRepository(registrations); + ReactiveOAuth2AuthorizedClientService authorizedClientService = + new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository); + return new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager( + clientRegistrationRepository, authorizedClientService); + } + } + + private String noSuchBeanExceptionMessage(final String className) { + return ".*No qualifying bean of type '.*" + className + "' available.*"; + } }