Browse Source
Non web applications might want to leverage `ReactiveClientRegistrationRepository` and `ServerOAuth2AuthorizedClientRepository` to configure `WebClient`. Closes gh-14350pull/14400/merge
6 changed files with 200 additions and 329 deletions
@ -1,60 +0,0 @@
@@ -1,60 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2018 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 |
||||
* |
||||
* http://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.boot.autoconfigure.security.oauth2.client.reactive; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
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; |
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Conditional; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
||||
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository; |
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; |
||||
|
||||
/** |
||||
* {@link Configuration} used to map {@link OAuth2ClientProperties} to client |
||||
* registrations. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
@Configuration |
||||
@EnableConfigurationProperties(OAuth2ClientProperties.class) |
||||
@Conditional(ClientsConfiguredCondition.class) |
||||
class ReactiveOAuth2ClientRegistrationRepositoryConfiguration { |
||||
|
||||
private final OAuth2ClientProperties properties; |
||||
|
||||
ReactiveOAuth2ClientRegistrationRepositoryConfiguration( |
||||
OAuth2ClientProperties properties) { |
||||
this.properties = properties; |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(ReactiveClientRegistrationRepository.class) |
||||
public InMemoryReactiveClientRegistrationRepository clientRegistrationRepository() { |
||||
List<ClientRegistration> registrations = new ArrayList<>( |
||||
OAuth2ClientPropertiesRegistrationAdapter |
||||
.getClientRegistrations(this.properties).values()); |
||||
return new InMemoryReactiveClientRegistrationRepository(registrations); |
||||
} |
||||
|
||||
} |
||||
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2018 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 |
||||
* |
||||
* http://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.boot.autoconfigure.security.oauth2.client.reactive; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService; |
||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; |
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; |
||||
|
||||
/** |
||||
* {@link Configuration} used to create an in-memory |
||||
* {@link ReactiveOAuth2AuthorizedClientService}. |
||||
* |
||||
* @author Madhura Bhave |
||||
* @since 2.1.0 |
||||
*/ |
||||
@Configuration |
||||
public class ReactiveOAuth2WebSecurityConfiguration { |
||||
|
||||
@Bean |
||||
@ConditionalOnBean(ReactiveClientRegistrationRepository.class) |
||||
@ConditionalOnMissingBean |
||||
public ReactiveOAuth2AuthorizedClientService authorizedClientService( |
||||
ReactiveClientRegistrationRepository clientRegistrationRepository) { |
||||
return new InMemoryReactiveOAuth2AuthorizedClientService( |
||||
clientRegistrationRepository); |
||||
} |
||||
|
||||
} |
||||
@ -1,65 +0,0 @@
@@ -1,65 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2018 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 |
||||
* |
||||
* http://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.boot.autoconfigure.security.oauth2.client.reactive; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; |
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link ReactiveOAuth2ClientRegistrationRepositoryConfiguration}. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
public class ReactiveOAuth2ClientRegistrationRepositoryConfigurationTests { |
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); |
||||
|
||||
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration.login"; |
||||
|
||||
@Test |
||||
public void clientRegistrationRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() { |
||||
this.contextRunner |
||||
.withUserConfiguration( |
||||
ReactiveOAuth2ClientRegistrationRepositoryConfiguration.class) |
||||
.run((context) -> assertThat(context) |
||||
.doesNotHaveBean(ClientRegistrationRepository.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void clientRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresent() { |
||||
this.contextRunner |
||||
.withUserConfiguration( |
||||
ReactiveOAuth2ClientRegistrationRepositoryConfiguration.class) |
||||
.withPropertyValues(REGISTRATION_PREFIX + ".foo.client-id=abcd", |
||||
REGISTRATION_PREFIX + ".foo.client-secret=secret", |
||||
REGISTRATION_PREFIX + ".foo.provider=github") |
||||
.run((context) -> { |
||||
ReactiveClientRegistrationRepository repository = context |
||||
.getBean(ReactiveClientRegistrationRepository.class); |
||||
ClientRegistration registration = repository |
||||
.findByRegistrationId("foo").block(); |
||||
assertThat(registration).isNotNull(); |
||||
assertThat(registration.getClientSecret()).isEqualTo("secret"); |
||||
}); |
||||
} |
||||
|
||||
} |
||||
@ -1,114 +0,0 @@
@@ -1,114 +0,0 @@
|
||||
/* |
||||
* Copyright 2012-2018 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 |
||||
* |
||||
* http://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.boot.autoconfigure.security.oauth2.client.reactive; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService; |
||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
||||
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository; |
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; |
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link ReactiveOAuth2WebSecurityConfiguration}. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
public class ReactiveOAuth2WebSecurityConfigurationTests { |
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); |
||||
|
||||
@Test |
||||
public void authorizedClientServiceBeanIsConditionalOnClientRegistrationRepository() { |
||||
this.contextRunner |
||||
.withUserConfiguration(ReactiveOAuth2WebSecurityConfiguration.class) |
||||
.run((context) -> assertThat(context) |
||||
.doesNotHaveBean(ReactiveOAuth2AuthorizedClientService.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void configurationRegistersAuthorizedClientServiceBean() { |
||||
this.contextRunner |
||||
.withUserConfiguration(ReactiveClientRepositoryConfiguration.class, |
||||
ReactiveOAuth2WebSecurityConfiguration.class) |
||||
.run((context) -> assertThat(context) |
||||
.hasSingleBean(ReactiveOAuth2AuthorizedClientService.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void authorizedClientServiceBeanIsConditionalOnMissingBean() { |
||||
this.contextRunner |
||||
.withUserConfiguration(OAuth2AuthorizedClientServiceConfiguration.class, |
||||
ReactiveOAuth2WebSecurityConfiguration.class) |
||||
.run((context) -> { |
||||
assertThat(context) |
||||
.hasSingleBean(ReactiveOAuth2AuthorizedClientService.class); |
||||
assertThat(context).hasBean("testAuthorizedClientService"); |
||||
}); |
||||
} |
||||
|
||||
@Configuration |
||||
static class ReactiveClientRepositoryConfiguration { |
||||
|
||||
@Bean |
||||
public ReactiveClientRegistrationRepository clientRegistrationRepository() { |
||||
List<ClientRegistration> registrations = new ArrayList<>(); |
||||
registrations.add(getClientRegistration("first", "http://user-info-uri.com")); |
||||
registrations.add(getClientRegistration("second", "http://other-user-info")); |
||||
return new InMemoryReactiveClientRegistrationRepository(registrations); |
||||
} |
||||
|
||||
private ClientRegistration getClientRegistration(String id, String userInfoUri) { |
||||
ClientRegistration.Builder builder = ClientRegistration |
||||
.withRegistrationId(id); |
||||
builder.clientName("foo").clientId("foo").clientAuthenticationMethod( |
||||
org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.scope("read").clientSecret("secret") |
||||
.redirectUriTemplate("http://redirect-uri.com") |
||||
.authorizationUri("http://authorization-uri.com") |
||||
.tokenUri("http://token-uri.com").userInfoUri(userInfoUri) |
||||
.userNameAttributeName("login"); |
||||
return builder.build(); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Configuration |
||||
@Import(ReactiveClientRepositoryConfiguration.class) |
||||
static class OAuth2AuthorizedClientServiceConfiguration { |
||||
|
||||
@Bean |
||||
public ReactiveOAuth2AuthorizedClientService testAuthorizedClientService( |
||||
ReactiveClientRegistrationRepository clientRegistrationRepository) { |
||||
return new InMemoryReactiveOAuth2AuthorizedClientService( |
||||
clientRegistrationRepository); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue