mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Revert OAuth2 Client Registration Grant Type Hierarchy
Closes gh-14554
This commit is contained in:
parent
546bd89f2e
commit
daa3d457b7
@ -16,7 +16,6 @@
|
||||
package org.springframework.boot.autoconfigure.security.oauth2.client;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -36,46 +35,32 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
* @author Madhura Bhave
|
||||
* @since 2.1.0
|
||||
*/
|
||||
|
||||
public class ClientsConfiguredCondition extends SpringBootCondition {
|
||||
|
||||
private static final Bindable<Map<String, OAuth2ClientProperties.LoginClientRegistration>> STRING_LOGIN_REGISTRATION_MAP = Bindable
|
||||
.mapOf(String.class, OAuth2ClientProperties.LoginClientRegistration.class);
|
||||
|
||||
private static final Bindable<Map<String, OAuth2ClientProperties.AuthorizationCodeClientRegistration>> STRING_AUTHORIZATION_CODE_REGISTRATION_MAP = Bindable
|
||||
.mapOf(String.class,
|
||||
OAuth2ClientProperties.AuthorizationCodeClientRegistration.class);
|
||||
private static final Bindable<Map<String, OAuth2ClientProperties.Registration>> STRING_REGISTRATION_MAP = Bindable
|
||||
.mapOf(String.class, OAuth2ClientProperties.Registration.class);
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
ConditionMessage.Builder message = ConditionMessage
|
||||
.forCondition("OAuth2 Clients Configured Condition");
|
||||
Map<String, OAuth2ClientProperties.BaseClientRegistration> registrations = getRegistrations(
|
||||
Map<String, OAuth2ClientProperties.Registration> registrations = getRegistrations(
|
||||
context.getEnvironment());
|
||||
if (!registrations.isEmpty()) {
|
||||
return ConditionOutcome.match(message.foundExactly(
|
||||
"registered clients " + registrations.values().stream().map(
|
||||
OAuth2ClientProperties.BaseClientRegistration::getClientId)
|
||||
return ConditionOutcome.match(message
|
||||
.foundExactly("registered clients " + registrations.values().stream()
|
||||
.map(OAuth2ClientProperties.Registration::getClientId)
|
||||
.collect(Collectors.joining(", "))));
|
||||
}
|
||||
return ConditionOutcome.noMatch(message.notAvailable("registered clients"));
|
||||
}
|
||||
|
||||
private Map<String, OAuth2ClientProperties.BaseClientRegistration> getRegistrations(
|
||||
private Map<String, OAuth2ClientProperties.Registration> getRegistrations(
|
||||
Environment environment) {
|
||||
Map<String, OAuth2ClientProperties.BaseClientRegistration> registrations = new HashMap<>();
|
||||
Map<String, OAuth2ClientProperties.LoginClientRegistration> loginClientRegistrations = Binder
|
||||
.get(environment).bind("spring.security.oauth2.client.registration.login",
|
||||
STRING_LOGIN_REGISTRATION_MAP)
|
||||
.orElse(Collections.emptyMap());
|
||||
Map<String, OAuth2ClientProperties.AuthorizationCodeClientRegistration> authCodeClientRegistrations = Binder
|
||||
.get(environment)
|
||||
.bind("spring.security.oauth2.client.registration.authorizationcode",
|
||||
STRING_AUTHORIZATION_CODE_REGISTRATION_MAP)
|
||||
.orElse(Collections.emptyMap());
|
||||
registrations.putAll(loginClientRegistrations);
|
||||
registrations.putAll(authCodeClientRegistrations);
|
||||
return registrations;
|
||||
return Binder.get(environment).bind("spring.security.oauth2.client.registration",
|
||||
STRING_REGISTRATION_MAP).orElse(Collections.emptyMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,116 +44,32 @@ public class OAuth2ClientProperties {
|
||||
/**
|
||||
* OAuth client registrations.
|
||||
*/
|
||||
private final Registration registration = new Registration();
|
||||
private final Map<String, Registration> registration = new HashMap<>();
|
||||
|
||||
public Map<String, Provider> getProvider() {
|
||||
return this.provider;
|
||||
}
|
||||
|
||||
public Registration getRegistration() {
|
||||
public Map<String, Registration> getRegistration() {
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void validate() {
|
||||
this.getRegistration().getLogin().values().forEach(this::validateRegistration);
|
||||
this.getRegistration().getAuthorizationCode().values()
|
||||
.forEach(this::validateRegistration);
|
||||
this.getRegistration().values().forEach(this::validateRegistration);
|
||||
}
|
||||
|
||||
private void validateRegistration(BaseClientRegistration registration) {
|
||||
private void validateRegistration(Registration registration) {
|
||||
if (!StringUtils.hasText(registration.getClientId())) {
|
||||
throw new IllegalStateException("Client id must not be empty.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A single client registration.
|
||||
*/
|
||||
public static class Registration {
|
||||
|
||||
/**
|
||||
* OpenID Connect client registrations.
|
||||
*/
|
||||
private Map<String, LoginClientRegistration> login = new HashMap<>();
|
||||
|
||||
/**
|
||||
* OAuth2 authorization_code client registrations.
|
||||
*/
|
||||
private Map<String, AuthorizationCodeClientRegistration> authorizationCode = new HashMap<>();
|
||||
|
||||
public Map<String, LoginClientRegistration> getLogin() {
|
||||
return this.login;
|
||||
}
|
||||
|
||||
public void setLogin(Map<String, LoginClientRegistration> login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public Map<String, AuthorizationCodeClientRegistration> getAuthorizationCode() {
|
||||
return this.authorizationCode;
|
||||
}
|
||||
|
||||
public void setAuthorizationCode(
|
||||
Map<String, AuthorizationCodeClientRegistration> authorizationCode) {
|
||||
this.authorizationCode = authorizationCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A single client registration for OpenID Connect login.
|
||||
*/
|
||||
public static class LoginClientRegistration extends BaseClientRegistration {
|
||||
|
||||
/**
|
||||
* Redirect URI. May be left blank when using a pre-defined provider.
|
||||
*/
|
||||
private String redirectUri;
|
||||
|
||||
public String getRedirectUri() {
|
||||
return this.redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getRedirectUriTemplate() {
|
||||
return getRedirectUri();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setRedirectUriTemplate(String redirectUri) {
|
||||
setRedirectUri(redirectUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A single client registration for OAuth2 authorization_code flow.
|
||||
*/
|
||||
public static class AuthorizationCodeClientRegistration
|
||||
extends BaseClientRegistration {
|
||||
|
||||
/**
|
||||
* Redirect URI for the registration.
|
||||
*/
|
||||
private String redirectUri;
|
||||
|
||||
public String getRedirectUri() {
|
||||
return this.redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for a single client registration.
|
||||
*/
|
||||
public static class BaseClientRegistration {
|
||||
|
||||
/**
|
||||
* Reference to the OAuth 2.0 provider to use. May reference an element from the
|
||||
* 'provider' property or used one of the commonly used providers (google, github,
|
||||
@ -182,6 +98,11 @@ public class OAuth2ClientProperties {
|
||||
*/
|
||||
private String authorizationGrantType;
|
||||
|
||||
/**
|
||||
* Redirect URI. May be left blank when using a pre-defined provider.
|
||||
*/
|
||||
private String redirectUri;
|
||||
|
||||
/**
|
||||
* Authorization scopes. May be left blank when using a pre-defined provider.
|
||||
*/
|
||||
@ -232,6 +153,24 @@ public class OAuth2ClientProperties {
|
||||
this.authorizationGrantType = authorizationGrantType;
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return this.redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getRedirectUriTemplate() {
|
||||
return getRedirectUri();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setRedirectUriTemplate(String redirectUri) {
|
||||
setRedirectUri(redirectUri);
|
||||
}
|
||||
|
||||
public Set<String> getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
@ -1,115 +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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.config.ConfigFileApplicationListener;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
/**
|
||||
* {@link EnvironmentPostProcessor} that migrates legacy OAuth2 login client properties
|
||||
* under the `spring.security.oauth2.client.login` prefix.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class OAuth2ClientPropertiesEnvironmentPostProcessor
|
||||
implements EnvironmentPostProcessor, Ordered {
|
||||
|
||||
private static final Bindable<Map<String, OAuth2ClientProperties.LoginClientRegistration>> STRING_LEGACY_REGISTRATION_MAP = Bindable
|
||||
.mapOf(String.class, OAuth2ClientProperties.LoginClientRegistration.class);
|
||||
|
||||
private static final String PREFIX = "spring.security.oauth2.client.registration";
|
||||
|
||||
private static final String LOGIN_REGISTRATION_PREFIX = PREFIX + ".login.";
|
||||
|
||||
private static final String UPDATED_PROPERTY_SOURCE_SUFFIX = "-updated-oauth-client";
|
||||
|
||||
private int order = ConfigFileApplicationListener.DEFAULT_ORDER + 1;
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment,
|
||||
SpringApplication application) {
|
||||
environment.getPropertySources().forEach((propertySource) -> {
|
||||
String name = propertySource.getName();
|
||||
Iterable<ConfigurationPropertySource> sources = ConfigurationPropertySources
|
||||
.from(propertySource);
|
||||
ConfigurationPropertySource source = sources.iterator().next();
|
||||
Binder binder = new Binder(sources);
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
MapPropertySource updatedPropertySource = new MapPropertySource(
|
||||
name + UPDATED_PROPERTY_SOURCE_SUFFIX, map);
|
||||
Map<String, OAuth2ClientProperties.LoginClientRegistration> registrations = binder
|
||||
.bind(PREFIX, STRING_LEGACY_REGISTRATION_MAP)
|
||||
.orElse(Collections.emptyMap());
|
||||
registrations.entrySet()
|
||||
.forEach((entry) -> addProperties(entry, source, map));
|
||||
if (!map.isEmpty()) {
|
||||
environment.getPropertySources().addBefore(name, updatedPropertySource);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addProperties(
|
||||
Map.Entry<String, OAuth2ClientProperties.LoginClientRegistration> entry,
|
||||
ConfigurationPropertySource source, Map<String, Object> map) {
|
||||
OAuth2ClientProperties.LoginClientRegistration registration = entry.getValue();
|
||||
String registrationId = entry.getKey();
|
||||
addProperty(registrationId, "client-id", registration::getClientId, map, source);
|
||||
addProperty(registrationId, "client-secret", registration::getClientSecret, map,
|
||||
source);
|
||||
addProperty(registrationId, "client-name", registration::getClientName, map,
|
||||
source);
|
||||
addProperty(registrationId, "redirect-uri-template", registration::getRedirectUri,
|
||||
map, source);
|
||||
addProperty(registrationId, "authorization-grant-type",
|
||||
registration::getAuthorizationGrantType, map, source);
|
||||
addProperty(registrationId, "client-authentication-method",
|
||||
registration::getClientAuthenticationMethod, map, source);
|
||||
addProperty(registrationId, "provider", registration::getProvider, map, source);
|
||||
addProperty(registrationId, "scope", registration::getScope, map, source);
|
||||
}
|
||||
|
||||
private void addProperty(String registrationId, String property,
|
||||
Supplier<Object> valueSupplier, Map<String, Object> map,
|
||||
ConfigurationPropertySource source) {
|
||||
String registrationKey = PREFIX + "." + registrationId + ".";
|
||||
String loginRegistrationKey = LOGIN_REGISTRATION_PREFIX + registrationId + ".";
|
||||
if (source.getConfigurationProperty(
|
||||
ConfigurationPropertyName.of(registrationKey + property)) != null) {
|
||||
map.put(loginRegistrationKey + property, valueSupplier.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
}
|
@ -50,35 +50,20 @@ public final class OAuth2ClientPropertiesRegistrationAdapter {
|
||||
public static Map<String, ClientRegistration> getClientRegistrations(
|
||||
OAuth2ClientProperties properties) {
|
||||
Map<String, ClientRegistration> clientRegistrations = new HashMap<>();
|
||||
properties.getRegistration().getLogin()
|
||||
.forEach((key, value) -> clientRegistrations.put(key,
|
||||
getLoginClientRegistration(key, value,
|
||||
properties.getProvider())));
|
||||
properties.getRegistration().getAuthorizationCode()
|
||||
.forEach((key, value) -> clientRegistrations.put(key,
|
||||
getAuthorizationCodeClientRegistration(key, value,
|
||||
properties.getProvider())));
|
||||
properties.getRegistration().forEach((key, value) -> clientRegistrations.put(key,
|
||||
getClientRegistration(key, value, properties.getProvider())));
|
||||
return clientRegistrations;
|
||||
}
|
||||
|
||||
private static ClientRegistration getAuthorizationCodeClientRegistration(
|
||||
String registrationId,
|
||||
OAuth2ClientProperties.AuthorizationCodeClientRegistration properties,
|
||||
Map<String, Provider> providers) {
|
||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||
Builder builder = getBuilder(map, registrationId, properties, providers);
|
||||
map.from(properties::getRedirectUri).to(builder::redirectUriTemplate);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static Builder getBuilder(PropertyMapper map, String registrationId,
|
||||
OAuth2ClientProperties.BaseClientRegistration properties,
|
||||
private static ClientRegistration getClientRegistration(String registrationId,
|
||||
OAuth2ClientProperties.Registration properties,
|
||||
Map<String, Provider> providers) {
|
||||
Builder builder = getBuilderFromIssuerIfPossible(registrationId,
|
||||
properties.getProvider(), providers);
|
||||
if (builder == null) {
|
||||
builder = getBuilder(registrationId, properties.getProvider(), providers);
|
||||
}
|
||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||
map.from(properties::getClientId).to(builder::clientId);
|
||||
map.from(properties::getClientSecret).to(builder::clientSecret);
|
||||
map.from(properties::getClientAuthenticationMethod)
|
||||
@ -86,18 +71,10 @@ public final class OAuth2ClientPropertiesRegistrationAdapter {
|
||||
.to(builder::clientAuthenticationMethod);
|
||||
map.from(properties::getAuthorizationGrantType).as(AuthorizationGrantType::new)
|
||||
.to(builder::authorizationGrantType);
|
||||
map.from(properties::getRedirectUri).to(builder::redirectUriTemplate);
|
||||
map.from(properties::getScope).as((scope) -> StringUtils.toStringArray(scope))
|
||||
.to(builder::scope);
|
||||
map.from(properties::getClientName).to(builder::clientName);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static ClientRegistration getLoginClientRegistration(String registrationId,
|
||||
OAuth2ClientProperties.LoginClientRegistration properties,
|
||||
Map<String, Provider> providers) {
|
||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||
Builder builder = getBuilder(map, registrationId, properties, providers);
|
||||
map.from(properties::getRedirectUri).to(builder::redirectUriTemplate);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
@ -711,15 +711,6 @@
|
||||
"name": "spring.session.hazelcast.flush-mode",
|
||||
"defaultValue": "on-save"
|
||||
},
|
||||
{
|
||||
"name" : "spring.security.oauth2.client.registration",
|
||||
"type" : "java.util.Map<java.lang.String,org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.LoginClientRegistration>",
|
||||
"description" : "Maps client registration-id to a client registration.",
|
||||
"deprecation" : {
|
||||
"replacement" : "spring.security.oauth2.client.registration.login",
|
||||
"level" : "warning"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.session.servlet.filter-dispatcher-types",
|
||||
"defaultValue": [
|
||||
|
@ -7,10 +7,6 @@ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingL
|
||||
org.springframework.context.ApplicationListener=\
|
||||
org.springframework.boot.autoconfigure.BackgroundPreinitializer
|
||||
|
||||
# Environment Post Processors
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=\
|
||||
org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesEnvironmentPostProcessor
|
||||
|
||||
# Auto Configuration Import Listeners
|
||||
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
|
||||
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
|
||||
|
@ -1,158 +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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.env.SystemEnvironmentPropertySource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OAuth2ClientPropertiesEnvironmentPostProcessor}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class OAuth2ClientPropertiesEnvironmentPostProcessorTests {
|
||||
|
||||
private OAuth2ClientPropertiesEnvironmentPostProcessor postProcessor = new OAuth2ClientPropertiesEnvironmentPostProcessor();
|
||||
|
||||
private MockEnvironment environment;
|
||||
|
||||
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration.github-client.";
|
||||
|
||||
private static final String ENVIRONMENT_REGISTRATION_PREFIX = "SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB-CLIENT_";
|
||||
|
||||
private static final String LOGIN_REGISTRATION_PREFIX = "spring.security.oauth2.client.registration.login.github-client.";
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.environment = new MockEnvironment();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorWhenLegacyPropertiesShouldConvert() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(REGISTRATION_PREFIX + "client-id", "my-client-id");
|
||||
properties.put(REGISTRATION_PREFIX + "client-secret", "my-client-secret");
|
||||
properties.put(REGISTRATION_PREFIX + "redirect-uri-template",
|
||||
"http://my-redirect-uri.com");
|
||||
properties.put(REGISTRATION_PREFIX + "provider", "github");
|
||||
properties.put(REGISTRATION_PREFIX + "scope", "user");
|
||||
properties.put(REGISTRATION_PREFIX + "client-name", "my-client-name");
|
||||
properties.put(REGISTRATION_PREFIX + "authorization-grant-type",
|
||||
"authorization_code");
|
||||
properties.put(REGISTRATION_PREFIX + "client-authentication-method", "FORM");
|
||||
MapPropertySource source = new MapPropertySource("test", properties);
|
||||
this.environment.getPropertySources().addFirst(source);
|
||||
this.postProcessor.postProcessEnvironment(this.environment, null);
|
||||
assertPropertyMigration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorDoesNotCopyMissingProperties() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(REGISTRATION_PREFIX + "client-id", "my-client-id");
|
||||
MapPropertySource source = new MapPropertySource("test", properties);
|
||||
this.environment.getPropertySources().addFirst(source);
|
||||
this.postProcessor.postProcessEnvironment(this.environment, null);
|
||||
assertThat(this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "client-id"))
|
||||
.isEqualTo("my-client-id");
|
||||
assertThat(
|
||||
this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "client-secret"))
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorWhenLegacyEnvironmentVariablesPropertiesShouldConvert() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "CLIENTID", "my-client-id");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "CLIENTSECRET",
|
||||
"my-client-secret");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "REDIRECTURITEMPLATE",
|
||||
"http://my-redirect-uri.com");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "PROVIDER", "github");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "SCOPE", "user");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "CLIENTNAME", "my-client-name");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "AUTHORIZATIONGRANTTYPE",
|
||||
"authorization_code");
|
||||
properties.put(ENVIRONMENT_REGISTRATION_PREFIX + "CLIENTAUTHENTICATIONMETHOD",
|
||||
"FORM");
|
||||
SystemEnvironmentPropertySource source = new SystemEnvironmentPropertySource(
|
||||
"test-" + StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
|
||||
properties);
|
||||
this.environment.getPropertySources().addFirst(source);
|
||||
this.postProcessor.postProcessEnvironment(this.environment, null);
|
||||
assertPropertyMigration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessorWhenNewPropertiesShouldDoNothing() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "client-id", "my-client-id");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "client-secret", "my-client-secret");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "redirect-uri-template",
|
||||
"http://my-redirect-uri.com");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "provider", "github");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "scope", "user");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "client-name", "my-client-name");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "authorization-grant-type",
|
||||
"authorization_code");
|
||||
properties.put(LOGIN_REGISTRATION_PREFIX + "client-authentication-method",
|
||||
"FORM");
|
||||
MapPropertySource source = new MapPropertySource("test", properties);
|
||||
this.environment.getPropertySources().addFirst(source);
|
||||
MutablePropertySources propertySources = new MutablePropertySources(
|
||||
this.environment.getPropertySources());
|
||||
this.postProcessor.postProcessEnvironment(this.environment, null);
|
||||
assertPropertyMigration();
|
||||
assertThat(this.environment.getPropertySources())
|
||||
.containsExactlyElementsOf(propertySources);
|
||||
}
|
||||
|
||||
private void assertPropertyMigration() {
|
||||
assertThat(this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "client-id"))
|
||||
.isEqualTo("my-client-id");
|
||||
assertThat(
|
||||
this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "client-secret"))
|
||||
.isEqualTo("my-client-secret");
|
||||
assertThat(this.environment
|
||||
.getProperty(LOGIN_REGISTRATION_PREFIX + "redirect-uri-template"))
|
||||
.isEqualTo("http://my-redirect-uri.com");
|
||||
assertThat(this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "provider"))
|
||||
.isEqualTo("github");
|
||||
assertThat(this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "scope"))
|
||||
.isEqualTo("user");
|
||||
assertThat(
|
||||
this.environment.getProperty(LOGIN_REGISTRATION_PREFIX + "client-name"))
|
||||
.isEqualTo("my-client-name");
|
||||
assertThat(this.environment
|
||||
.getProperty(LOGIN_REGISTRATION_PREFIX + "authorization-grant-type"))
|
||||
.isEqualTo("authorization_code");
|
||||
assertThat(this.environment
|
||||
.getProperty(LOGIN_REGISTRATION_PREFIX + "client-authentication-method"))
|
||||
.isEqualTo("FORM");
|
||||
}
|
||||
|
||||
}
|
@ -26,8 +26,8 @@ import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.LoginClientRegistration;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.Provider;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.Registration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -68,16 +68,16 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
provider.setUserInfoAuthenticationMethod("form");
|
||||
provider.setUserNameAttribute("sub");
|
||||
provider.setJwkSetUri("http://example.com/jwk");
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
login.setProvider("provider");
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
login.setClientAuthenticationMethod("post");
|
||||
login.setAuthorizationGrantType("authorization_code");
|
||||
login.setRedirectUri("http://example.com/redirect");
|
||||
login.setScope(Collections.singleton("scope"));
|
||||
login.setClientName("clientName");
|
||||
properties.getRegistration().getLogin().put("registration", login);
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setProvider("provider");
|
||||
registration.setClientId("clientId");
|
||||
registration.setClientSecret("clientSecret");
|
||||
registration.setClientAuthenticationMethod("post");
|
||||
registration.setAuthorizationGrantType("authorization_code");
|
||||
registration.setRedirectUri("http://example.com/redirect");
|
||||
registration.setScope(Collections.singleton("scope"));
|
||||
registration.setClientName("clientName");
|
||||
properties.getRegistration().put("registration", registration);
|
||||
properties.getProvider().put("provider", provider);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
@ -110,11 +110,11 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
@Test
|
||||
public void getClientRegistrationsWhenUsingCommonProviderShouldAdapt() {
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
login.setProvider("google");
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
properties.getRegistration().getLogin().put("registration", login);
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setProvider("google");
|
||||
registration.setClientId("clientId");
|
||||
registration.setClientSecret("clientSecret");
|
||||
properties.getRegistration().put("registration", registration);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
ClientRegistration adapted = registrations.get("registration");
|
||||
@ -145,16 +145,16 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
@Test
|
||||
public void getClientRegistrationsWhenUsingCommonProviderWithOverrideShouldAdapt() {
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
login.setProvider("google");
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
login.setClientAuthenticationMethod("post");
|
||||
login.setAuthorizationGrantType("authorization_code");
|
||||
login.setRedirectUri("http://example.com/redirect");
|
||||
login.setScope(Collections.singleton("scope"));
|
||||
login.setClientName("clientName");
|
||||
properties.getRegistration().getLogin().put("registration", login);
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setProvider("google");
|
||||
registration.setClientId("clientId");
|
||||
registration.setClientSecret("clientSecret");
|
||||
registration.setClientAuthenticationMethod("post");
|
||||
registration.setAuthorizationGrantType("authorization_code");
|
||||
registration.setRedirectUri("http://example.com/redirect");
|
||||
registration.setScope(Collections.singleton("scope"));
|
||||
registration.setClientName("clientName");
|
||||
properties.getRegistration().put("registration", registration);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
ClientRegistration adapted = registrations.get("registration");
|
||||
@ -188,9 +188,9 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
@Test
|
||||
public void getClientRegistrationsWhenUnknownProviderShouldThrowException() {
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
login.setProvider("missing");
|
||||
properties.getRegistration().getLogin().put("registration", login);
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setProvider("missing");
|
||||
properties.getRegistration().put("registration", registration);
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties))
|
||||
@ -200,10 +200,10 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
@Test
|
||||
public void getClientRegistrationsWhenProviderNotSpecifiedShouldUseRegistrationId() {
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
properties.getRegistration().getLogin().put("google", login);
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setClientId("clientId");
|
||||
registration.setClientSecret("clientSecret");
|
||||
properties.getRegistration().put("google", registration);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
ClientRegistration adapted = registrations.get("google");
|
||||
@ -232,47 +232,11 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
assertThat(adapted.getClientName()).isEqualTo("Google");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getClientRegistrationsWhenAuthorizationCodeClientShouldAdapt() {
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
OAuth2ClientProperties.AuthorizationCodeClientRegistration registration = new OAuth2ClientProperties.AuthorizationCodeClientRegistration();
|
||||
registration.setClientId("clientId");
|
||||
registration.setClientSecret("clientSecret");
|
||||
registration.setRedirectUri("http://my-redirect-uri.com");
|
||||
properties.getRegistration().getAuthorizationCode().put("google", registration);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
ClientRegistration adapted = registrations.get("google");
|
||||
ProviderDetails adaptedProvider = adapted.getProviderDetails();
|
||||
assertThat(adaptedProvider.getAuthorizationUri())
|
||||
.isEqualTo("https://accounts.google.com/o/oauth2/v2/auth");
|
||||
assertThat(adaptedProvider.getTokenUri())
|
||||
.isEqualTo("https://www.googleapis.com/oauth2/v4/token");
|
||||
assertThat(adaptedProvider.getUserInfoEndpoint().getUri())
|
||||
.isEqualTo("https://www.googleapis.com/oauth2/v3/userinfo");
|
||||
assertThat(adaptedProvider.getUserInfoEndpoint().getAuthenticationMethod())
|
||||
.isEqualTo(
|
||||
org.springframework.security.oauth2.core.AuthenticationMethod.HEADER);
|
||||
assertThat(adaptedProvider.getJwkSetUri())
|
||||
.isEqualTo("https://www.googleapis.com/oauth2/v3/certs");
|
||||
assertThat(adapted.getRegistrationId()).isEqualTo("google");
|
||||
assertThat(adapted.getClientId()).isEqualTo("clientId");
|
||||
assertThat(adapted.getClientSecret()).isEqualTo("clientSecret");
|
||||
assertThat(adapted.getRedirectUriTemplate())
|
||||
.isEqualTo("http://my-redirect-uri.com");
|
||||
assertThat(adapted.getClientAuthenticationMethod()).isEqualTo(
|
||||
org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC);
|
||||
assertThat(adapted.getAuthorizationGrantType()).isEqualTo(
|
||||
org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE);
|
||||
assertThat(adapted.getScopes()).containsExactly("openid", "profile", "email");
|
||||
assertThat(adapted.getClientName()).isEqualTo("Google");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getClientRegistrationsWhenProviderNotSpecifiedAndUnknownProviderShouldThrowException() {
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
properties.getRegistration().getLogin().put("missing", login);
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
properties.getRegistration().put("missing", registration);
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties))
|
||||
@ -283,7 +247,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
@Test
|
||||
public void oidcProviderConfigurationWhenProviderNotSpecifiedOnRegistration()
|
||||
throws Exception {
|
||||
LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
Registration login = new OAuth2ClientProperties.Registration();
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
testOidcConfiguration(login, "okta");
|
||||
@ -292,7 +256,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
@Test
|
||||
public void oidcProviderConfigurationWhenProviderSpecifiedOnRegistration()
|
||||
throws Exception {
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new LoginClientRegistration();
|
||||
OAuth2ClientProperties.Registration login = new Registration();
|
||||
login.setProvider("okta-oidc");
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
@ -307,13 +271,13 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
String issuer = this.server.url("").toString();
|
||||
String cleanIssuerPath = cleanIssuerPath(issuer);
|
||||
setupMockResponse(cleanIssuerPath);
|
||||
OAuth2ClientProperties.LoginClientRegistration login = new OAuth2ClientProperties.LoginClientRegistration();
|
||||
login.setProvider("okta-oidc");
|
||||
login.setClientId("clientId");
|
||||
login.setClientSecret("clientSecret");
|
||||
login.setClientAuthenticationMethod("post");
|
||||
login.setRedirectUri("http://example.com/redirect");
|
||||
login.setScope(Collections.singleton("user"));
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setProvider("okta-oidc");
|
||||
registration.setClientId("clientId");
|
||||
registration.setClientSecret("clientSecret");
|
||||
registration.setClientAuthenticationMethod("post");
|
||||
registration.setRedirectUri("http://example.com/redirect");
|
||||
registration.setScope(Collections.singleton("user"));
|
||||
Provider provider = new Provider();
|
||||
provider.setIssuerUri(issuer);
|
||||
provider.setAuthorizationUri("http://example.com/auth");
|
||||
@ -323,7 +287,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
provider.setJwkSetUri("http://example.com/jwk");
|
||||
OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
properties.getProvider().put("okta-oidc", provider);
|
||||
properties.getRegistration().getLogin().put("okta", login);
|
||||
properties.getRegistration().put("okta", registration);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
ClientRegistration adapted = registrations.get("okta");
|
||||
@ -347,8 +311,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
.isEqualTo("sub");
|
||||
}
|
||||
|
||||
private void testOidcConfiguration(
|
||||
OAuth2ClientProperties.LoginClientRegistration registration,
|
||||
private void testOidcConfiguration(OAuth2ClientProperties.Registration registration,
|
||||
String providerId) throws Exception {
|
||||
this.server = new MockWebServer();
|
||||
this.server.start();
|
||||
@ -359,7 +322,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
|
||||
Provider provider = new Provider();
|
||||
provider.setIssuerUri(issuer);
|
||||
properties.getProvider().put(providerId, provider);
|
||||
properties.getRegistration().getLogin().put("okta", registration);
|
||||
properties.getRegistration().put("okta", registration);
|
||||
Map<String, ClientRegistration> registrations = OAuth2ClientPropertiesRegistrationAdapter
|
||||
.getClientRegistrations(properties);
|
||||
ClientRegistration adapted = registrations.get("okta");
|
||||
|
@ -18,9 +18,6 @@ package org.springframework.boot.autoconfigure.security.oauth2.client;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.AuthorizationCodeClientRegistration;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.LoginClientRegistration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
@ -34,40 +31,21 @@ public class OAuth2ClientPropertiesTests {
|
||||
private OAuth2ClientProperties properties = new OAuth2ClientProperties();
|
||||
|
||||
@Test
|
||||
public void clientIdAbsentForLoginClientsThrowsException() {
|
||||
LoginClientRegistration registration = new LoginClientRegistration();
|
||||
public void clientIdAbsentThrowsException() {
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setClientSecret("secret");
|
||||
registration.setProvider("google");
|
||||
this.properties.getRegistration().getLogin().put("foo", registration);
|
||||
this.properties.getRegistration().put("foo", registration);
|
||||
assertThatIllegalStateException().isThrownBy(this.properties::validate)
|
||||
.withMessageContaining("Client id must not be empty.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientSecretAbsentShouldNotThrowException() {
|
||||
LoginClientRegistration registration = new LoginClientRegistration();
|
||||
OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
|
||||
registration.setClientId("foo");
|
||||
registration.setProvider("google");
|
||||
this.properties.getRegistration().getLogin().put("foo", registration);
|
||||
this.properties.validate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientIdAbsentForAuthorizationCodeClientsThrowsException() {
|
||||
AuthorizationCodeClientRegistration registration = new AuthorizationCodeClientRegistration();
|
||||
registration.setClientSecret("secret");
|
||||
registration.setProvider("google");
|
||||
this.properties.getRegistration().getAuthorizationCode().put("foo", registration);
|
||||
assertThatIllegalStateException().isThrownBy(this.properties::validate)
|
||||
.withMessageContaining("Client id must not be empty.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientSecretAbsentForAuthorizationCodeClientDoesNotThrowException() {
|
||||
AuthorizationCodeClientRegistration registration = new AuthorizationCodeClientRegistration();
|
||||
registration.setClientId("foo");
|
||||
registration.setProvider("google");
|
||||
this.properties.getRegistration().getAuthorizationCode().put("foo", registration);
|
||||
this.properties.getRegistration().put("foo", registration);
|
||||
this.properties.validate();
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class ReactiveOAuth2ClientAutoConfigurationTests {
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ReactiveOAuth2ClientAutoConfiguration.class));
|
||||
|
||||
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration.login";
|
||||
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration";
|
||||
|
||||
@Test
|
||||
public void autoConfigurationShouldBackOffForServletEnvironments() {
|
||||
|
@ -33,7 +33,7 @@ public class OAuth2ClientRegistrationRepositoryConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration.login";
|
||||
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration";
|
||||
|
||||
@Test
|
||||
public void clientRegistrationRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() {
|
||||
|
@ -3264,13 +3264,31 @@ Spring.
|
||||
==== Client
|
||||
If you have `spring-security-oauth2-client` on your classpath, you can take advantage of
|
||||
some auto-configuration to make it easy to set up an OAuth2/Open ID Connect clients. This configuration
|
||||
makes use of the properties under `OAuth2ClientProperties`.
|
||||
makes use of the properties under `OAuth2ClientProperties`. The same properties are applicable to both servlet and reactive applications.
|
||||
|
||||
You can register multiple OAuth2/OpenID Connect providers under the `spring.security.oauth2.client.provider`
|
||||
prefix, as shown in the following example:
|
||||
You can register multiple OAuth2 clients and providers under the
|
||||
`spring.security.oauth2.client` prefix, as shown in the following example:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.security.oauth2.client.registration.my-client-1.client-id=abcd
|
||||
spring.security.oauth2.client.registration.my-client-1.client-secret=password
|
||||
spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope
|
||||
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider
|
||||
spring.security.oauth2.client.registration.my-client-1.scope=user
|
||||
spring.security.oauth2.client.registration.my-client-1.redirect-uri-template=http://my-redirect-uri.com
|
||||
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic
|
||||
spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code
|
||||
|
||||
spring.security.oauth2.client.registration.my-client-2.client-id=abcd
|
||||
spring.security.oauth2.client.registration.my-client-2.client-secret=password
|
||||
spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope
|
||||
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider
|
||||
spring.security.oauth2.client.registration.my-client-2.scope=email
|
||||
spring.security.oauth2.client.registration.my-client-2.redirect-uri-template=http://my-redirect-uri.com
|
||||
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic
|
||||
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code
|
||||
|
||||
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://my-auth-server/oauth/authorize
|
||||
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=http://my-auth-server/oauth/token
|
||||
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=http://my-auth-server/userinfo
|
||||
@ -3294,33 +3312,6 @@ Provider can be configured with the `issuer-uri`:
|
||||
|
||||
|
||||
|
||||
[[boot-features-security-oauth2-login-client-registration]]
|
||||
===== OpenID Connect Login client registration
|
||||
|
||||
You can register multiple Open ID Connect clients under the
|
||||
`spring.security.oauth2.client.registration.login` prefix, as shown in the following example:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.security.oauth2.client.registration.login.my-client-1.client-id=abcd
|
||||
spring.security.oauth2.client.registration.login.my-client-1.client-secret=password
|
||||
spring.security.oauth2.client.registration.login.my-client-1.client-name=Client for user scope
|
||||
spring.security.oauth2.client.registration.login.my-client-1.provider=my-oauth-provider
|
||||
spring.security.oauth2.client.registration.login.my-client-1.scope=user
|
||||
spring.security.oauth2.client.registration.login.my-client-1.redirect-uri=http://localhost:8080/login/oauth2/code/my-client-1
|
||||
spring.security.oauth2.client.registration.login.my-client-1.client-authentication-method=basic
|
||||
spring.security.oauth2.client.registration.login.my-client-1.authorization-grant-type=authorization_code
|
||||
|
||||
spring.security.oauth2.client.registration.login.my-client-2.client-id=abcd
|
||||
spring.security.oauth2.client.registration.login.my-client-2.client-secret=password
|
||||
spring.security.oauth2.client.registration.login.my-client-2.client-name=Client for email scope
|
||||
spring.security.oauth2.client.registration.login.my-client-2.provider=my-oauth-provider
|
||||
spring.security.oauth2.client.registration.login.my-client-2.scope=email
|
||||
spring.security.oauth2.client.registration.login.my-client-2.redirect-uri=http://localhost:8080/login/oauth2/code/my-client-2
|
||||
spring.security.oauth2.client.registration.login.my-client-2.client-authentication-method=basic
|
||||
spring.security.oauth2.client.registration.login.my-client-2.authorization-grant-type=authorization_code
|
||||
----
|
||||
|
||||
By default, Spring Security's `OAuth2LoginAuthenticationFilter` only processes URLs
|
||||
matching `/login/oauth2/code/*`. If you want to customize the `redirect-uri` to
|
||||
use a different pattern, you need to provide configuration to process that custom pattern.
|
||||
@ -3344,36 +3335,6 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
}
|
||||
----
|
||||
|
||||
The same properties are applicable to both servlet and reactive applications.
|
||||
|
||||
|
||||
[[boot-features-security-oauth2-authorization-code-client-registration]]
|
||||
===== OAuth2 Authorization Code client registration
|
||||
|
||||
You can register multiple OAuth2 `authorization_code` clients under the
|
||||
`spring.security.oauth2.client.registration.authorization-code` prefix, as shown in the following example:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-id=abcd
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-secret=password
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-name=Client for user scope
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.provider=my-oauth-provider
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.scope=user
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.redirect-uri=http://my-redirect-uri.com
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.client-authentication-method=basic
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-1.authorization-grant-type=authorization_code
|
||||
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-id=abcd
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-secret=password
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-name=Client for email scope
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.provider=my-oauth-provider
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.scope=email
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.redirect-uri=http://my-redirect-uri.com
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.client-authentication-method=basic
|
||||
spring.security.oauth2.client.registration.authorization-code.my-client-2.authorization-grant-type=authorization_code
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[boot-features-security-oauth2-common-providers]]
|
||||
@ -3383,19 +3344,19 @@ we provide a set of provider defaults (`google`, `github`, `facebook`, and `okta
|
||||
respectively).
|
||||
|
||||
If you do not need to customize these providers, you can set the `provider` attribute to
|
||||
the one for which you need to infer defaults. Also, if the ID of your client matches the
|
||||
the one for which you need to infer defaults. Also, if the key for the client registration matches a
|
||||
default supported provider, Spring Boot infers that as well.
|
||||
|
||||
In other words, the two configurations in the following example use the Google provider:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.security.oauth2.client.registration.login.my-client.client-id=abcd
|
||||
spring.security.oauth2.client.registration.login.my-client.client-secret=password
|
||||
spring.security.oauth2.client.registration.login.my-client.provider=google
|
||||
spring.security.oauth2.client.registration.my-client.client-id=abcd
|
||||
spring.security.oauth2.client.registration.my-client.client-secret=password
|
||||
spring.security.oauth2.client.registration.my-client.provider=google
|
||||
|
||||
spring.security.oauth2.client.registration.login.google.client-id=abcd
|
||||
spring.security.oauth2.client.registration.login.google.client-secret=password
|
||||
spring.security.oauth2.client.registration.google.client-id=abcd
|
||||
spring.security.oauth2.client.registration.google.client-secret=password
|
||||
----
|
||||
|
||||
|
||||
|
@ -3,32 +3,30 @@ spring:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
login:
|
||||
github-client-1:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github user
|
||||
provider: github
|
||||
scope: user
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
github-client-2:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github email
|
||||
provider: github
|
||||
scope: user:email
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
yahoo-oidc:
|
||||
client-id: ${YAHOO-CLIENT-ID}
|
||||
client-secret: ${YAHOO-CLIENT-SECRET}
|
||||
authorization_code:
|
||||
github-repos:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
scope: public_repo
|
||||
redirect-uri: "{baseUrl}/github-repos"
|
||||
provider: github
|
||||
client-name: GitHub Repositories
|
||||
github-client-1:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github user
|
||||
provider: github
|
||||
scope: user
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
github-client-2:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github email
|
||||
provider: github
|
||||
scope: user:email
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
yahoo-oidc:
|
||||
client-id: ${YAHOO-CLIENT-ID}
|
||||
client-secret: ${YAHOO-CLIENT-SECRET}
|
||||
github-repos:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
scope: public_repo
|
||||
redirect-uri: "{baseUrl}/github-repos"
|
||||
provider: github
|
||||
client-name: GitHub Repositories
|
||||
provider:
|
||||
yahoo-oidc:
|
||||
issuer-uri: https://api.login.yahoo.com/
|
@ -53,20 +53,13 @@ public class SampleOAuth2ClientApplicationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginShouldHaveBothOAuth2LoginClientsToChooseFrom() {
|
||||
public void loginShouldHaveAllOAuth2ClientsToChooseFrom() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("/oauth2/authorization/yahoo");
|
||||
assertThat(entity.getBody()).contains("/oauth2/authorization/github-client-1");
|
||||
assertThat(entity.getBody()).contains("/oauth2/authorization/github-client-2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authorizationCodeClientIsPresent() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("/oauth2/authorization/github-repos");
|
||||
}
|
||||
|
||||
|
@ -3,24 +3,23 @@ spring:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
login:
|
||||
github-client-1:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github user
|
||||
provider: github
|
||||
scope: user
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
github-client-2:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github email
|
||||
provider: github
|
||||
scope: user:email
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
yahoo-oidc:
|
||||
client-id: ${YAHOO-CLIENT-ID}
|
||||
client-secret: ${YAHOO-CLIENT-SECRET}
|
||||
github-client-1:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github user
|
||||
provider: github
|
||||
scope: user
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
github-client-2:
|
||||
client-id: ${APP-CLIENT-ID}
|
||||
client-secret: ${APP-CLIENT-SECRET}
|
||||
client-name: Github email
|
||||
provider: github
|
||||
scope: user:email
|
||||
redirect-uri: http://localhost:8080/login/oauth2/code/github
|
||||
yahoo-oidc:
|
||||
client-id: ${YAHOO-CLIENT-ID}
|
||||
client-secret: ${YAHOO-CLIENT-SECRET}
|
||||
provider:
|
||||
yahoo-oidc:
|
||||
issuer-uri: https://api.login.yahoo.com/
|
Loading…
Reference in New Issue
Block a user