Browse Source

Rename ClientRegistration.clientAlias -> registrationId

Fixes gh-4575
Joe Grandja 8 years ago
parent
commit
814742fef6
18 changed files with 198 additions and 196 deletions
  1. 5 5
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java
  2. 4 4
      config/src/main/resources/org/springframework/security/config/oauth2/client/spring-security-oauth2-client-templates.properties
  3. 24 23
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java
  4. 8 9
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationProperties.java
  5. 2 2
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationRepository.java
  6. 5 5
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java
  7. 3 3
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/RegistrationIdIdentifierStrategy.java
  8. 0 3
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java
  9. 6 6
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilter.java
  10. 7 7
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java
  11. 1 2
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java
  12. 2 3
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java
  13. 6 6
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/TestUtil.java
  14. 31 36
      samples/boot/oauth2login/README.adoc
  15. 12 12
      samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java
  16. 28 14
      samples/boot/oauth2login/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ClientRegistrationAutoConfiguration.java
  17. 37 40
      samples/boot/oauth2login/src/main/resources/META-INF/oauth2-clients-defaults.yml
  18. 17 16
      samples/boot/oauth2login/src/main/resources/application.yml

+ 5 - 5
config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java

@@ -44,7 +44,7 @@ import java.util.Arrays;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import static org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter.CLIENT_ALIAS_URI_VARIABLE_NAME;
+import static org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter.REGISTRATION_ID_URI_VARIABLE_NAME;
 
 /**
  * @author Joe Grandja
@@ -244,10 +244,10 @@ public final class OAuth2LoginConfigurer<H extends HttpSecurityBuilder<H>> exten
 				RequestMatcher authorizationRequestMatcher = OAuth2LoginConfigurer.this.authorizationCodeRequestRedirectFilterConfigurer.getAuthorizationRequestMatcher();
 				if (authorizationRequestMatcher != null && AntPathRequestMatcher.class.isAssignableFrom(authorizationRequestMatcher.getClass())) {
 					String authorizationRequestPattern =  ((AntPathRequestMatcher)authorizationRequestMatcher).getPattern();
-					String clientAliasTemplateVariable = "{" + CLIENT_ALIAS_URI_VARIABLE_NAME + "}";
-					if (authorizationRequestPattern.endsWith(clientAliasTemplateVariable)) {
+					String registrationIdTemplateVariable = "{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}";
+					if (authorizationRequestPattern.endsWith(registrationIdTemplateVariable)) {
 						authorizationRequestBaseUri = authorizationRequestPattern.substring(
-							0, authorizationRequestPattern.length() - clientAliasTemplateVariable.length() - 1);
+							0, authorizationRequestPattern.length() - registrationIdTemplateVariable.length() - 1);
 					} else {
 						authorizationRequestBaseUri = authorizationRequestPattern;
 					}
@@ -257,7 +257,7 @@ public final class OAuth2LoginConfigurer<H extends HttpSecurityBuilder<H>> exten
 
 				Map<String, String> oauth2AuthenticationUrlToClientName = clientRegistrationRepository.getRegistrations().stream()
 					.collect(Collectors.toMap(
-						e -> authorizationRequestBaseUri + "/" + e.getClientAlias(),
+						e -> authorizationRequestBaseUri + "/" + e.getRegistrationId(),
 						e -> e.getClientName()));
 				loginPageGeneratingFilter.setOauth2LoginEnabled(true);
 				loginPageGeneratingFilter.setOauth2AuthenticationUrlToClientName(oauth2AuthenticationUrlToClientName);

+ 4 - 4
config/src/main/resources/org/springframework/security/config/oauth2/client/spring-security-oauth2-client-templates.properties

@@ -1,7 +1,7 @@
 # Google
 spring.security.oauth2.client.templates.google.client-authentication-method=basic
 spring.security.oauth2.client.templates.google.authorization-grant-type=authorization_code
-spring.security.oauth2.client.templates.google.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}
+spring.security.oauth2.client.templates.google.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}
 spring.security.oauth2.client.templates.google.scope=openid, profile, email, address, phone
 spring.security.oauth2.client.templates.google.authorization-uri=https://accounts.google.com/o/oauth2/v2/auth
 spring.security.oauth2.client.templates.google.token-uri=https://www.googleapis.com/oauth2/v4/token
@@ -13,7 +13,7 @@ spring.security.oauth2.client.templates.google.client-alias=google
 # GitHub
 spring.security.oauth2.client.templates.github.client-authentication-method=basic
 spring.security.oauth2.client.templates.github.authorization-grant-type=authorization_code
-spring.security.oauth2.client.templates.github.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}
+spring.security.oauth2.client.templates.github.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}
 spring.security.oauth2.client.templates.github.scope=user
 spring.security.oauth2.client.templates.github.authorization-uri=https://github.com/login/oauth/authorize
 spring.security.oauth2.client.templates.github.token-uri=https://github.com/login/oauth/access_token
@@ -25,7 +25,7 @@ spring.security.oauth2.client.templates.github.client-alias=github
 # Facebook
 spring.security.oauth2.client.templates.facebook.client-authentication-method=post
 spring.security.oauth2.client.templates.facebook.authorization-grant-type=authorization_code
-spring.security.oauth2.client.templates.facebook.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}
+spring.security.oauth2.client.templates.facebook.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}
 spring.security.oauth2.client.templates.facebook.scope=public_profile, email
 spring.security.oauth2.client.templates.facebook.authorization-uri=https://www.facebook.com/v2.8/dialog/oauth
 spring.security.oauth2.client.templates.facebook.token-uri=https://graph.facebook.com/v2.8/oauth/access_token
@@ -37,7 +37,7 @@ spring.security.oauth2.client.templates.facebook.client-alias=facebook
 # Okta
 spring.security.oauth2.client.templates.okta.client-authentication-method=basic
 spring.security.oauth2.client.templates.okta.authorization-grant-type=authorization_code
-spring.security.oauth2.client.templates.okta.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}
+spring.security.oauth2.client.templates.okta.redirect-uri={scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}
 spring.security.oauth2.client.templates.okta.scope=openid, profile, email, address, phone
 spring.security.oauth2.client.templates.okta.client-name=Okta
 spring.security.oauth2.client.templates.okta.client-alias=okta

+ 24 - 23
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java

@@ -33,6 +33,7 @@ import java.util.Set;
  * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-2">Section 2 Client Registration</a>
  */
 public class ClientRegistration {
+	private String registrationId;
 	private String clientId;
 	private String clientSecret;
 	private ClientAuthenticationMethod clientAuthenticationMethod = ClientAuthenticationMethod.BASIC;
@@ -41,11 +42,18 @@ public class ClientRegistration {
 	private Set<String> scope = Collections.emptySet();
 	private ProviderDetails providerDetails = new ProviderDetails();
 	private String clientName;
-	private String clientAlias;
 
 	protected ClientRegistration() {
 	}
 
+	public String getRegistrationId() {
+		return this.registrationId;
+	}
+
+	protected void setRegistrationId(String registrationId) {
+		this.registrationId = registrationId;
+	}
+
 	public String getClientId() {
 		return this.clientId;
 	}
@@ -110,14 +118,6 @@ public class ClientRegistration {
 		this.clientName = clientName;
 	}
 
-	public String getClientAlias() {
-		return this.clientAlias;
-	}
-
-	protected void setClientAlias(String clientAlias) {
-		this.clientAlias = clientAlias;
-	}
-
 	public class ProviderDetails {
 		private String authorizationUri;
 		private String tokenUri;
@@ -185,6 +185,7 @@ public class ClientRegistration {
 	}
 
 	public static class Builder {
+		protected String registrationId;
 		protected String clientId;
 		protected String clientSecret;
 		protected ClientAuthenticationMethod clientAuthenticationMethod = ClientAuthenticationMethod.BASIC;
@@ -197,14 +198,14 @@ public class ClientRegistration {
 		protected String userNameAttributeName;
 		protected String jwkSetUri;
 		protected String clientName;
-		protected String clientAlias;
 
-		public Builder(String clientId) {
-			this.clientId = clientId;
+		public Builder(String registrationId) {
+			this.registrationId = registrationId;
 		}
 
 		public Builder(ClientRegistrationProperties clientRegistrationProperties) {
-			this(clientRegistrationProperties.getClientId());
+			this(clientRegistrationProperties.getRegistrationId());
+			this.clientId(clientRegistrationProperties.getClientId());
 			this.clientSecret(clientRegistrationProperties.getClientSecret());
 			this.clientAuthenticationMethod(clientRegistrationProperties.getClientAuthenticationMethod());
 			this.authorizationGrantType(clientRegistrationProperties.getAuthorizationGrantType());
@@ -218,11 +219,11 @@ public class ClientRegistration {
 			this.userNameAttributeName(clientRegistrationProperties.getUserNameAttributeName());
 			this.jwkSetUri(clientRegistrationProperties.getJwkSetUri());
 			this.clientName(clientRegistrationProperties.getClientName());
-			this.clientAlias(clientRegistrationProperties.getClientAlias());
 		}
 
 		public Builder(ClientRegistration clientRegistration) {
-			this(clientRegistration.getClientId());
+			this(clientRegistration.getRegistrationId());
+			this.clientId(clientRegistration.getClientId());
 			this.clientSecret(clientRegistration.getClientSecret());
 			this.clientAuthenticationMethod(clientRegistration.getClientAuthenticationMethod());
 			this.authorizationGrantType(clientRegistration.getAuthorizationGrantType());
@@ -236,7 +237,11 @@ public class ClientRegistration {
 			this.userNameAttributeName(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName());
 			this.jwkSetUri(clientRegistration.getProviderDetails().getJwkSetUri());
 			this.clientName(clientRegistration.getClientName());
-			this.clientAlias(clientRegistration.getClientAlias());
+		}
+
+		public Builder clientId(String clientId) {
+			this.clientId = clientId;
+			return this;
 		}
 
 		public Builder clientSecret(String clientSecret) {
@@ -297,11 +302,6 @@ public class ClientRegistration {
 			return this;
 		}
 
-		public Builder clientAlias(String clientAlias) {
-			this.clientAlias = clientAlias;
-			return this;
-		}
-
 		public ClientRegistration build() {
 			this.validateClientWithAuthorizationCodeGrantType();
 			ClientRegistration clientRegistration = new ClientRegistration();
@@ -310,6 +310,7 @@ public class ClientRegistration {
 		}
 
 		protected void setProperties(ClientRegistration clientRegistration) {
+			clientRegistration.setRegistrationId(this.registrationId);
 			clientRegistration.setClientId(this.clientId);
 			clientRegistration.setClientSecret(this.clientSecret);
 			clientRegistration.setClientAuthenticationMethod(this.clientAuthenticationMethod);
@@ -326,12 +327,12 @@ public class ClientRegistration {
 			clientRegistration.setProviderDetails(providerDetails);
 
 			clientRegistration.setClientName(this.clientName);
-			clientRegistration.setClientAlias(this.clientAlias);
 		}
 
 		protected void validateClientWithAuthorizationCodeGrantType() {
 			Assert.isTrue(AuthorizationGrantType.AUTHORIZATION_CODE.equals(this.authorizationGrantType),
 				"authorizationGrantType must be " + AuthorizationGrantType.AUTHORIZATION_CODE.getValue());
+			Assert.hasText(this.registrationId, "registrationId cannot be empty");
 			Assert.hasText(this.clientId, "clientId cannot be empty");
 			Assert.hasText(this.clientSecret, "clientSecret cannot be empty");
 			Assert.notNull(this.clientAuthenticationMethod, "clientAuthenticationMethod cannot be null");
@@ -341,7 +342,7 @@ public class ClientRegistration {
 			Assert.hasText(this.tokenUri, "tokenUri cannot be empty");
 			Assert.hasText(this.userInfoUri, "userInfoUri cannot be empty");
 			Assert.hasText(this.clientName, "clientName cannot be empty");
-			Assert.hasText(this.clientAlias, "clientAlias cannot be empty");
+			Assert.hasText(this.registrationId, "registrationId cannot be empty");
 		}
 	}
 }

+ 8 - 9
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationProperties.java

@@ -33,6 +33,7 @@ import java.util.Set;
  * @see ClientRegistration
  */
 public class ClientRegistrationProperties {
+	private String registrationId;
 	private String clientId;
 	private String clientSecret;
 	private ClientAuthenticationMethod clientAuthenticationMethod = ClientAuthenticationMethod.BASIC;
@@ -45,8 +46,14 @@ public class ClientRegistrationProperties {
 	private String userNameAttributeName;
 	private String jwkSetUri;
 	private String clientName;
-	private String clientAlias;
 
+	public String getRegistrationId() {
+		return this.registrationId;
+	}
+
+	public void setRegistrationId(String registrationId) {
+		this.registrationId = registrationId;
+	}
 
 	public String getClientId() {
 		return this.clientId;
@@ -143,12 +150,4 @@ public class ClientRegistrationProperties {
 	public void setClientName(String clientName) {
 		this.clientName = clientName;
 	}
-
-	public String getClientAlias() {
-		return this.clientAlias;
-	}
-
-	public void setClientAlias(String clientAlias) {
-		this.clientAlias = clientAlias;
-	}
 }

+ 2 - 2
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationRepository.java

@@ -33,9 +33,9 @@ import java.util.List;
  */
 public interface ClientRegistrationRepository {
 
-	List<ClientRegistration> getRegistrationsByClientId(String clientId);
+	List<ClientRegistration> findByClientId(String clientId);
 
-	ClientRegistration getRegistrationByClientAlias(String clientAlias);
+	ClientRegistration findByRegistrationId(String registrationId);
 
 	List<ClientRegistration> getRegistrations();
 

+ 5 - 5
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java

@@ -32,7 +32,7 @@ import java.util.stream.Collectors;
  * @see ClientRegistration
  */
 public final class InMemoryClientRegistrationRepository implements ClientRegistrationRepository {
-	private final ClientRegistrationIdentifierStrategy<String> identifierStrategy = new ClientAliasIdentifierStrategy();
+	private final ClientRegistrationIdentifierStrategy<String> identifierStrategy = new RegistrationIdIdentifierStrategy();
 	private final Map<String, ClientRegistration> registrations;
 
 	public InMemoryClientRegistrationRepository(List<ClientRegistration> registrations) {
@@ -49,7 +49,7 @@ public final class InMemoryClientRegistrationRepository implements ClientRegistr
 	}
 
 	@Override
-	public List<ClientRegistration> getRegistrationsByClientId(String clientId) {
+	public List<ClientRegistration> findByClientId(String clientId) {
 		Assert.hasText(clientId, "clientId cannot be empty");
 		return this.registrations.values().stream()
 			.filter(registration -> registration.getClientId().equals(clientId))
@@ -57,10 +57,10 @@ public final class InMemoryClientRegistrationRepository implements ClientRegistr
 	}
 
 	@Override
-	public ClientRegistration getRegistrationByClientAlias(String clientAlias) {
-		Assert.hasText(clientAlias, "clientAlias cannot be empty");
+	public ClientRegistration findByRegistrationId(String registrationId) {
+		Assert.hasText(registrationId, "registrationId cannot be empty");
 		return this.registrations.values().stream()
-			.filter(registration -> registration.getClientAlias().equals(clientAlias))
+			.filter(registration -> registration.getRegistrationId().equals(registrationId))
 			.findFirst()
 			.orElse(null);
 	}

+ 3 - 3
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientAliasIdentifierStrategy.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/RegistrationIdIdentifierStrategy.java

@@ -19,17 +19,17 @@ import org.springframework.util.Assert;
 
 /**
  * A {@link ClientRegistrationIdentifierStrategy} that identifies a {@link ClientRegistration}
- * using the {@link ClientRegistration#getClientAlias()}.
+ * using the {@link ClientRegistration#getRegistrationId()}.
  *
  * @author Joe Grandja
  * @since 5.0
  * @see ClientRegistration
  */
-public class ClientAliasIdentifierStrategy implements ClientRegistrationIdentifierStrategy<String> {
+public class RegistrationIdIdentifierStrategy implements ClientRegistrationIdentifierStrategy<String> {
 
 	@Override
 	public String getIdentifier(ClientRegistration clientRegistration) {
 		Assert.notNull(clientRegistration, "clientRegistration cannot be null");
-		return clientRegistration.getClientAlias();
+		return clientRegistration.getRegistrationId();
 	}
 }

+ 0 - 3
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java

@@ -77,9 +77,6 @@ public final class InMemoryAccessTokenRepository implements SecurityTokenReposit
 			// Access Token Response attributes
 			builder.append("[").append(clientRegistration.getScope().toString()).append("]");
 
-			// Client alias is unique as well
-			builder.append("[").append(clientRegistration.getClientAlias()).append("]");
-
 			return Base64.getEncoder().encodeToString(builder.toString().getBytes());
 		}
 	}

+ 6 - 6
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilter.java

@@ -111,8 +111,8 @@ import java.io.IOException;
  */
 public class AuthorizationCodeAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
 	public static final String DEFAULT_AUTHORIZATION_RESPONSE_BASE_URI = "/oauth2/authorize/code";
-	public static final String CLIENT_ALIAS_URI_VARIABLE_NAME = "clientAlias";
-	public static final String DEFAULT_AUTHORIZATION_RESPONSE_URI = DEFAULT_AUTHORIZATION_RESPONSE_BASE_URI + "/{" + CLIENT_ALIAS_URI_VARIABLE_NAME + "}";
+	public static final String REGISTRATION_ID_URI_VARIABLE_NAME = "registrationId";
+	public static final String DEFAULT_AUTHORIZATION_RESPONSE_URI = DEFAULT_AUTHORIZATION_RESPONSE_BASE_URI + "/{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}";
 	private static final String AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE = "authorization_request_not_found";
 	private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
 	private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
@@ -141,11 +141,11 @@ public class AuthorizationCodeAuthenticationProcessingFilter extends AbstractAut
 
 		AuthorizationRequestAttributes matchingAuthorizationRequest = this.resolveAuthorizationRequest(request);
 
-		String clientAlias = ((RequestVariablesExtractor)this.getAuthorizationResponseMatcher())
-			.extractUriTemplateVariables(request).get(CLIENT_ALIAS_URI_VARIABLE_NAME);
+		String registrationId = ((RequestVariablesExtractor)this.getAuthorizationResponseMatcher())
+			.extractUriTemplateVariables(request).get(REGISTRATION_ID_URI_VARIABLE_NAME);
 		ClientRegistration clientRegistration = null;
-		if (!StringUtils.isEmpty(clientAlias)) {
-			clientRegistration = this.getClientRegistrationRepository().getRegistrationByClientAlias(clientAlias);
+		if (!StringUtils.isEmpty(registrationId)) {
+			clientRegistration = this.getClientRegistrationRepository().findByRegistrationId(registrationId);
 		}
 		if (clientRegistration == null || !matchingAuthorizationRequest.getClientId().equals(clientRegistration.getClientId())) {
 			OAuth2Error oauth2Error = new OAuth2Error(OAuth2Error.INVALID_REQUEST_ERROR_CODE);

+ 7 - 7
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java

@@ -61,8 +61,8 @@ import java.util.Map;
  */
 public class AuthorizationCodeRequestRedirectFilter extends OncePerRequestFilter {
 	public static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization/code";
-	public static final String CLIENT_ALIAS_URI_VARIABLE_NAME = "clientAlias";
-	public static final String DEFAULT_AUTHORIZATION_REQUEST_URI = DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/{" + CLIENT_ALIAS_URI_VARIABLE_NAME + "}";
+	public static final String REGISTRATION_ID_URI_VARIABLE_NAME = "registrationId";
+	public static final String DEFAULT_AUTHORIZATION_REQUEST_URI = DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}";
 	private RequestMatcher authorizationRequestMatcher;
 	private final ClientRegistrationRepository clientRegistrationRepository;
 	private final AuthorizationRequestUriBuilder authorizationUriBuilder;
@@ -113,11 +113,11 @@ public class AuthorizationCodeRequestRedirectFilter extends OncePerRequestFilter
 	protected void sendRedirectForAuthorizationCode(HttpServletRequest request, HttpServletResponse response)
 			throws IOException, ServletException {
 
-		String clientAlias = ((RequestVariablesExtractor)this.authorizationRequestMatcher)
-				.extractUriTemplateVariables(request).get(CLIENT_ALIAS_URI_VARIABLE_NAME);
-		ClientRegistration clientRegistration = this.clientRegistrationRepository.getRegistrationByClientAlias(clientAlias);
+		String registrationId = ((RequestVariablesExtractor)this.authorizationRequestMatcher)
+				.extractUriTemplateVariables(request).get(REGISTRATION_ID_URI_VARIABLE_NAME);
+		ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
 		if (clientRegistration == null) {
-			throw new IllegalArgumentException("Invalid Client Identifier (Alias): " + clientAlias);
+			throw new IllegalArgumentException("Invalid Client Identifier (Registration Id): " + registrationId);
 		}
 
 		String redirectUriStr = this.expandRedirectUri(request, clientRegistration);
@@ -152,7 +152,7 @@ public class AuthorizationCodeRequestRedirectFilter extends OncePerRequestFilter
 		uriVariables.put("serverName", request.getServerName());
 		uriVariables.put("serverPort", String.valueOf(request.getServerPort()));
 		uriVariables.put("contextPath", request.getContextPath());
-		uriVariables.put("clientAlias", clientRegistration.getClientAlias());
+		uriVariables.put("registrationId", clientRegistration.getRegistrationId());
 
 		return UriComponentsBuilder.fromUriString(clientRegistration.getRedirectUri())
 			.buildAndExpand(uriVariables)

+ 1 - 2
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java

@@ -41,7 +41,6 @@ import javax.servlet.http.HttpServletResponse;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.*;
 
 /**
  * Tests {@link AuthorizationCodeAuthenticationProcessingFilter}.
@@ -247,7 +246,7 @@ public class AuthorizationCodeAuthenticationProcessingFilterTests {
 	}
 
 	private MockHttpServletRequest setupRequest(ClientRegistration clientRegistration) {
-		String requestURI = TestUtil.AUTHORIZE_BASE_URI + "/" + clientRegistration.getClientAlias();
+		String requestURI = TestUtil.AUTHORIZE_BASE_URI + "/" + clientRegistration.getRegistrationId();
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI);
 		request.setScheme(TestUtil.DEFAULT_SCHEME);
 		request.setServerName(TestUtil.DEFAULT_SERVER_NAME);

+ 2 - 3
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java

@@ -31,7 +31,6 @@ import javax.servlet.http.HttpServletResponse;
 import java.net.URI;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.*;
 
 /**
  * Tests {@link AuthorizationCodeRequestRedirectFilter}.
@@ -75,7 +74,7 @@ public class AuthorizationCodeRequestRedirectFilterTests {
 		AuthorizationCodeRequestRedirectFilter filter =
 				setupFilter(authorizationUri, clientRegistration);
 
-		String requestUri = TestUtil.AUTHORIZATION_BASE_URI + "/" + clientRegistration.getClientAlias();
+		String requestUri = TestUtil.AUTHORIZATION_BASE_URI + "/" + clientRegistration.getRegistrationId();
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
 		request.setServletPath(requestUri);
 		MockHttpServletResponse response = new MockHttpServletResponse();
@@ -97,7 +96,7 @@ public class AuthorizationCodeRequestRedirectFilterTests {
 		AuthorizationRequestRepository authorizationRequestRepository = new HttpSessionAuthorizationRequestRepository();
 		filter.setAuthorizationRequestRepository(authorizationRequestRepository);
 
-		String requestUri = TestUtil.AUTHORIZATION_BASE_URI + "/" + clientRegistration.getClientAlias();
+		String requestUri = TestUtil.AUTHORIZATION_BASE_URI + "/" + clientRegistration.getRegistrationId();
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
 		request.setServletPath(requestUri);
 		MockHttpServletResponse response = new MockHttpServletResponse();

+ 6 - 6
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/TestUtil.java

@@ -34,24 +34,24 @@ class TestUtil {
 	static final String DEFAULT_SERVER_URL = DEFAULT_SCHEME + "://" + DEFAULT_SERVER_NAME + ":" + DEFAULT_SERVER_PORT;
 	static final String AUTHORIZATION_BASE_URI = "/oauth2/authorization/code";
 	static final String AUTHORIZE_BASE_URI = "/oauth2/authorize/code";
-	static final String GOOGLE_CLIENT_ALIAS = "google";
-	static final String GITHUB_CLIENT_ALIAS = "github";
+	static final String GOOGLE_REGISTRATION_ID = "google";
+	static final String GITHUB_REGISTRATION_ID = "github";
 
 	static ClientRegistrationRepository clientRegistrationRepository(ClientRegistration... clientRegistrations) {
 		return new InMemoryClientRegistrationRepository(Arrays.asList(clientRegistrations));
 	}
 
 	static ClientRegistration googleClientRegistration() {
-		return googleClientRegistration(DEFAULT_SERVER_URL + AUTHORIZE_BASE_URI + "/" + GOOGLE_CLIENT_ALIAS);
+		return googleClientRegistration(DEFAULT_SERVER_URL + AUTHORIZE_BASE_URI + "/" + GOOGLE_REGISTRATION_ID);
 	}
 
 	static ClientRegistration googleClientRegistration(String redirectUri) {
 		ClientRegistrationProperties clientRegistrationProperties = new ClientRegistrationProperties();
+		clientRegistrationProperties.setRegistrationId(GOOGLE_REGISTRATION_ID);
 		clientRegistrationProperties.setClientId("google-client-id");
 		clientRegistrationProperties.setClientSecret("secret");
 		clientRegistrationProperties.setAuthorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
 		clientRegistrationProperties.setClientName("Google Client");
-		clientRegistrationProperties.setClientAlias(GOOGLE_CLIENT_ALIAS);
 		clientRegistrationProperties.setAuthorizationUri("https://accounts.google.com/o/oauth2/auth");
 		clientRegistrationProperties.setTokenUri("https://accounts.google.com/o/oauth2/token");
 		clientRegistrationProperties.setUserInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
@@ -61,16 +61,16 @@ class TestUtil {
 	}
 
 	static ClientRegistration githubClientRegistration() {
-		return githubClientRegistration(DEFAULT_SERVER_URL + AUTHORIZE_BASE_URI + "/" + GITHUB_CLIENT_ALIAS);
+		return githubClientRegistration(DEFAULT_SERVER_URL + AUTHORIZE_BASE_URI + "/" + GITHUB_REGISTRATION_ID);
 	}
 
 	static ClientRegistration githubClientRegistration(String redirectUri) {
 		ClientRegistrationProperties clientRegistrationProperties = new ClientRegistrationProperties();
+		clientRegistrationProperties.setRegistrationId(GITHUB_REGISTRATION_ID);
 		clientRegistrationProperties.setClientId("github-client-id");
 		clientRegistrationProperties.setClientSecret("secret");
 		clientRegistrationProperties.setAuthorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
 		clientRegistrationProperties.setClientName("GitHub Client");
-		clientRegistrationProperties.setClientAlias(GITHUB_CLIENT_ALIAS);
 		clientRegistrationProperties.setAuthorizationUri("https://github.com/login/oauth/authorize");
 		clientRegistrationProperties.setTokenUri("https://github.com/login/oauth/access_token");
 		clientRegistrationProperties.setUserInfoUri("https://api.github.com/user");

+ 31 - 36
samples/boot/oauth2login/README.adoc

@@ -67,7 +67,7 @@ and have granted access to the OAuth Client _(created from the <<google-login-re
 
 For the sub-section, *_"Set a redirect URI"_*, ensure the *Authorised redirect URIs* is set to *http://localhost:8080/oauth2/authorize/code/google*
 
-TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{clientAlias}"_*.
+TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{registrationId}"_*.
  See <<oauth2-client-properties, OAuth client properties>> for more details on this default.
 
 [[google-login-configure-application-yml]]
@@ -93,7 +93,7 @@ Replace *${client-id}* and *${client-secret}* with the OAuth 2.0 credentials cre
 .OAuth client properties
 ====
 . *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
-. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.google*.
+. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.google*.
 . At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
  A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
 ====
@@ -133,7 +133,7 @@ While registering your application, ensure the *Authorization callback URL* is s
 NOTE: The *Authorization callback URL* (or redirect URI) is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with GitHub
  and have granted access to the OAuth application on the *Authorize application* page.
 
-TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{clientAlias}"_*.
+TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{registrationId}"_*.
  See <<oauth2-client-properties, OAuth client properties>> for more details on this default.
 
 After completing the registration, you should have created a new *OAuth Application* with credentials consisting of a *Client ID* and *Client Secret*.
@@ -161,7 +161,7 @@ Replace *${client-id}* and *${client-secret}* with the OAuth 2.0 credentials cre
 .OAuth client properties
 ====
 . *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
-. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.github*.
+. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.github*.
 . At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
  A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
 ====
@@ -210,7 +210,7 @@ For the field *Valid OAuth redirect URIs*, enter *http://localhost:8080/oauth2/a
 NOTE: The *OAuth redirect URI* is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with Facebook
  and have granted access to the application on the *Authorize application* page.
 
-TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{clientAlias}"_*.
+TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{registrationId}"_*.
  See <<oauth2-client-properties, OAuth client properties>> for more details on this default.
 
 Your application has now been assigned new OAuth 2.0 credentials under *App ID* and *App Secret*.
@@ -238,7 +238,7 @@ Replace *${app-id}* and *${app-secret}* with the OAuth 2.0 credentials created i
 .OAuth client properties
 ====
 . *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
-. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.facebook*.
+. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.facebook*.
 . At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
  A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
 ====
@@ -285,7 +285,7 @@ On the _"Configure OpenID Connect"_ page, enter *http://localhost:8080/oauth2/au
 NOTE: The *Redirect URI* is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with Okta
  and have granted access to the application on the *Authorize application* page.
 
-TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{clientAlias}"_*.
+TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{registrationId}"_*.
  See <<oauth2-client-properties, OAuth client properties>> for more details on this default.
 
 The next page presented displays the _"General"_ tab selected for the application.
@@ -326,7 +326,7 @@ As well, replace *${account-subdomain}* in _authorization-uri_, _token-uri_, _us
 .OAuth client properties
 ====
 . *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
-. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.okta*.
+. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.okta*.
 . At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
  A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
 ====
@@ -425,7 +425,7 @@ The following provides an overview of the Spring Boot auto-configuration classes
 *_org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration_*::
 `ClientRegistrationAutoConfiguration` is responsible for registering a `ClientRegistrationRepository` _bean_ with the `ApplicationContext`.
 The `ClientRegistrationRepository` is composed of one or more `ClientRegistration` instances, which are created from the OAuth client properties
-configured in the `Environment` that are prefixed with `security.oauth2.client.[client-key]`, for example, `security.oauth2.client.google`.
+configured in the `Environment` that are prefixed with `security.oauth2.client.registrations.[registration-id]`, for example, `security.oauth2.client.registrations.google`.
 
 NOTE: `ClientRegistrationAutoConfiguration` also loads a _resource_ named *oauth2-clients-defaults.yml*,
  which provides a set of default client property values for a number of _well-known_ Providers.
@@ -446,7 +446,7 @@ The following specifies the common set of properties available for configuring a
 [TIP]
 ====
 - *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
-- Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.google*.
+- Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.google*.
 - At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
 ====
 
@@ -456,7 +456,7 @@ The following specifies the common set of properties available for configuring a
 - *redirect-uri* - this is the client's _registered_ redirect URI that the _Authorization Server_ redirects the end-user's user-agent
  to after the end-user has authenticated and authorized access for the client.
 
-NOTE: The default redirect URI is _"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{clientAlias}"_, which leverages *URI template variables*.
+NOTE: The default redirect URI is _"{scheme}://{serverName}:{serverPort}/oauth2/authorize/code/{registrationId}"_, which leverages *URI template variables*.
 
 - *scopes* - a comma-delimited string of scope(s) requested during the _Authorization Request_ flow, for example: _openid, email, profile_
 
@@ -477,7 +477,7 @@ IMPORTANT: Standard _OAuth 2.0 Provider's_ may vary the naming of their *Name* a
  This is a *_required_* property for `DefaultOAuth2User`.
 
 - *client-name* - this is a descriptive name used for the client. The name may be used in certain scenarios, for example, when displaying the name of the client in the _auto-generated login page_.
-- *client-alias* - an _alias_ which uniquely identifies the client. It *must be* unique within a `ClientRegistrationRepository`.
+- *registration-id* - an _id_ which uniquely identifies the client registration. It *must be* unique within a `ClientRegistrationRepository`.
 
 [[oauth2-default-client-properties]]
 === Default client property values
@@ -499,41 +499,37 @@ security:
       google:
         client-authentication-method: basic
         authorized-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{clientAlias}"
+        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
         scopes: openid, email, profile
         authorization-uri: "https://accounts.google.com/o/oauth2/auth"
         token-uri: "https://accounts.google.com/o/oauth2/token"
         user-info-uri: "https://www.googleapis.com/oauth2/v3/userinfo"
         jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs
         client-name: Google
-        client-alias: google
       github:
         client-authentication-method: basic
         authorized-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{clientAlias}"
+        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
         scopes: user
         authorization-uri: "https://github.com/login/oauth/authorize"
         token-uri: "https://github.com/login/oauth/access_token"
         user-info-uri: "https://api.github.com/user"
         client-name: GitHub
-        client-alias: github
       facebook:
         client-authentication-method: post
         authorized-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{clientAlias}"
+        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
         scopes: public_profile, email
         authorization-uri: "https://www.facebook.com/v2.8/dialog/oauth"
         token-uri: "https://graph.facebook.com/v2.8/oauth/access_token"
         user-info-uri: "https://graph.facebook.com/me"
         client-name: Facebook
-        client-alias: facebook
       okta:
         client-authentication-method: basic
         authorized-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{clientAlias}"
+        redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
         scopes: openid, email, profile
         client-name: Okta
-        client-alias: okta
 ----
 
 = Appendix
@@ -552,18 +548,17 @@ Let's assume we have a _properties file_ named *oauth2-clients.properties* on th
 .oauth2-clients.properties
 [source,properties]
 ----
-security.oauth2.client.google.client-id=${client-id}
-security.oauth2.client.google.client-secret=${client-secret}
-security.oauth2.client.google.client-authentication-method=basic
-security.oauth2.client.google.authorized-grant-type=authorization_code
-security.oauth2.client.google.redirect-uri=http://localhost:8080/oauth2/authorize/code/google
-security.oauth2.client.google.scopes=openid,email,profile
-security.oauth2.client.google.authorization-uri=https://accounts.google.com/o/oauth2/auth
-security.oauth2.client.google.token-uri=https://accounts.google.com/o/oauth2/token
-security.oauth2.client.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
-security.oauth2.client.google.jwk-set-uri=https://www.googleapis.com/oauth2/v3/certs
-security.oauth2.client.google.client-name=Google
-security.oauth2.client.google.client-alias=google
+security.oauth2.client.registrations.google.client-id=${client-id}
+security.oauth2.client.registrations.google.client-secret=${client-secret}
+security.oauth2.client.registrations.google.client-authentication-method=basic
+security.oauth2.client.registrations.google.authorized-grant-type=authorization_code
+security.oauth2.client.registrations.google.redirect-uri=http://localhost:8080/oauth2/authorize/code/google
+security.oauth2.client.registrations.google.scopes=openid,email,profile
+security.oauth2.client.registrations.google.authorization-uri=https://accounts.google.com/o/oauth2/auth
+security.oauth2.client.registrations.google.token-uri=https://accounts.google.com/o/oauth2/token
+security.oauth2.client.registrations.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
+security.oauth2.client.registrations.google.jwk-set-uri=https://www.googleapis.com/oauth2/v3/certs
+security.oauth2.client.registrations.google.client-name=Google
 ----
 
 The following _security configuration_ will enable OAuth 2.0 Login using _Google_ as the _Authentication Provider_:
@@ -592,12 +587,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 	@Bean
 	public ClientRegistrationRepository clientRegistrationRepository() {
 		List<ClientRegistration> clientRegistrations = Collections.singletonList(
-			clientRegistration("security.oauth2.client.google."));
+			clientRegistration("security.oauth2.client.registrations.google."));
 
 		return new InMemoryClientRegistrationRepository(clientRegistrations);
 	}
 
 	private ClientRegistration clientRegistration(String clientPropertyKey) {
+		String registrationId = this.environment.getProperty(clientPropertyKey + "registration-id");
 		String clientId = this.environment.getProperty(clientPropertyKey + "client-id");
 		String clientSecret = this.environment.getProperty(clientPropertyKey + "client-secret");
 		ClientAuthenticationMethod clientAuthenticationMethod = new ClientAuthenticationMethod(
@@ -611,9 +607,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 		String userInfoUri = this.environment.getProperty(clientPropertyKey + "user-info-uri");
 		String jwkSetUri = this.environment.getProperty(clientPropertyKey + "jwk-set-uri");
 		String clientName = this.environment.getProperty(clientPropertyKey + "client-name");
-		String clientAlias = this.environment.getProperty(clientPropertyKey + "client-alias");
 
-		return new ClientRegistration.Builder(clientId)
+		return new ClientRegistration.Builder(registrationId)
+			.clientId(clientId)
 			.clientSecret(clientSecret)
 			.clientAuthenticationMethod(clientAuthenticationMethod)
 			.authorizedGrantType(authorizationGrantType)
@@ -624,7 +620,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 			.userInfoUri(userInfoUri)
 			.jwkSetUri(jwkSetUri)
 			.clientName(clientName)
-			.clientAlias(clientAlias)
 			.build();
 	}
 }

+ 12 - 12
samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java

@@ -93,10 +93,10 @@ public class OAuth2LoginApplicationTests {
 	@Before
 	public void setup() {
 		this.webClient.getCookieManager().clearCookies();
-		this.googleClientRegistration = this.clientRegistrationRepository.getRegistrationByClientAlias("google");
-		this.githubClientRegistration = this.clientRegistrationRepository.getRegistrationByClientAlias("github");
-		this.facebookClientRegistration = this.clientRegistrationRepository.getRegistrationByClientAlias("facebook");
-		this.oktaClientRegistration = this.clientRegistrationRepository.getRegistrationByClientAlias("okta");
+		this.googleClientRegistration = this.clientRegistrationRepository.findByRegistrationId("google");
+		this.githubClientRegistration = this.clientRegistrationRepository.findByRegistrationId("github");
+		this.facebookClientRegistration = this.clientRegistrationRepository.findByRegistrationId("facebook");
+		this.oktaClientRegistration = this.clientRegistrationRepository.findByRegistrationId("okta");
 	}
 
 	@Test
@@ -134,7 +134,7 @@ public class OAuth2LoginApplicationTests {
 
 		assertThat(params.get(OAuth2Parameter.RESPONSE_TYPE)).isEqualTo(ResponseType.CODE.getValue());
 		assertThat(params.get(OAuth2Parameter.CLIENT_ID)).isEqualTo(this.githubClientRegistration.getClientId());
-		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.githubClientRegistration.getClientAlias();
+		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.githubClientRegistration.getRegistrationId();
 		assertThat(URLDecoder.decode(params.get(OAuth2Parameter.REDIRECT_URI), "UTF-8")).isEqualTo(redirectUri);
 		assertThat(URLDecoder.decode(params.get(OAuth2Parameter.SCOPE), "UTF-8"))
 				.isEqualTo(this.githubClientRegistration.getScope().stream().collect(Collectors.joining(" ")));
@@ -194,7 +194,7 @@ public class OAuth2LoginApplicationTests {
 
 		String code = "auth-code";
 		String state = "state";
-		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.googleClientRegistration.getClientAlias();
+		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.googleClientRegistration.getRegistrationId();
 
 		String authorizationResponseUri =
 				UriComponentsBuilder.fromHttpUrl(redirectUri)
@@ -226,7 +226,7 @@ public class OAuth2LoginApplicationTests {
 
 		String code = "auth-code";
 		String state = "invalid-state";
-		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.githubClientRegistration.getClientAlias();
+		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.githubClientRegistration.getRegistrationId();
 
 		String authorizationResponseUri =
 				UriComponentsBuilder.fromHttpUrl(redirectUri)
@@ -284,7 +284,7 @@ public class OAuth2LoginApplicationTests {
 
 		String error = OAuth2Error.INVALID_CLIENT_ERROR_CODE;
 		String state = "state";
-		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.githubClientRegistration.getClientAlias();
+		String redirectUri = AUTHORIZE_BASE_URL + "/" + this.githubClientRegistration.getRegistrationId();
 
 		String authorizationResponseUri =
 				UriComponentsBuilder.fromHttpUrl(redirectUri)
@@ -309,10 +309,10 @@ public class OAuth2LoginApplicationTests {
 		assertThat(clientAnchorElements.size()).isEqualTo(expectedClients);
 
 		String baseAuthorizeUri = AUTHORIZATION_BASE_URI + "/";
-		String googleClientAuthorizeUri = baseAuthorizeUri + this.googleClientRegistration.getClientAlias();
-		String githubClientAuthorizeUri = baseAuthorizeUri + this.githubClientRegistration.getClientAlias();
-		String facebookClientAuthorizeUri = baseAuthorizeUri + this.facebookClientRegistration.getClientAlias();
-		String oktaClientAuthorizeUri = baseAuthorizeUri + this.oktaClientRegistration.getClientAlias();
+		String googleClientAuthorizeUri = baseAuthorizeUri + this.googleClientRegistration.getRegistrationId();
+		String githubClientAuthorizeUri = baseAuthorizeUri + this.githubClientRegistration.getRegistrationId();
+		String facebookClientAuthorizeUri = baseAuthorizeUri + this.facebookClientRegistration.getRegistrationId();
+		String oktaClientAuthorizeUri = baseAuthorizeUri + this.oktaClientRegistration.getRegistrationId();
 
 		for (int i=0; i<expectedClients; i++) {
 			assertThat(clientAnchorElements.get(i).getAttribute("href")).isIn(

+ 28 - 14
samples/boot/oauth2login/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ClientRegistrationAutoConfiguration.java

@@ -17,12 +17,21 @@ package org.springframework.boot.autoconfigure.security.oauth2.client;
 
 import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.condition.*;
+import org.springframework.boot.autoconfigure.condition.ConditionMessage;
+import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
 import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
 import org.springframework.boot.context.properties.bind.BindResult;
 import org.springframework.boot.context.properties.bind.Bindable;
 import org.springframework.boot.context.properties.bind.Binder;
-import org.springframework.context.annotation.*;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ConfigurationCondition;
 import org.springframework.core.env.ConfigurableEnvironment;
 import org.springframework.core.env.Environment;
 import org.springframework.core.env.MutablePropertySources;
@@ -35,7 +44,11 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
 import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
 import org.springframework.util.CollectionUtils;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -49,7 +62,7 @@ import java.util.stream.Collectors;
 public class ClientRegistrationAutoConfiguration {
 	private static final String CLIENTS_DEFAULTS_RESOURCE = "META-INF/oauth2-clients-defaults.yml";
 	static final String CLIENT_ID_PROPERTY = "client-id";
-	static final String CLIENT_PROPERTY_PREFIX = "security.oauth2.client";
+	static final String REGISTRATIONS_PROPERTY_PREFIX = "security.oauth2.client.registrations";
 
 	@Configuration
 	@Conditional(ClientPropertiesAvailableCondition.class)
@@ -69,14 +82,15 @@ public class ClientRegistrationAutoConfiguration {
 			}
 			Binder binder = Binder.get(this.environment);
 			List<ClientRegistration> clientRegistrations = new ArrayList<>();
-			Set<String> clientPropertyKeys = resolveClientPropertyKeys(this.environment);
-			for (String clientPropertyKey : clientPropertyKeys) {
-				String fullClientPropertyKey = CLIENT_PROPERTY_PREFIX + "." + clientPropertyKey;
-				if (!this.environment.containsProperty(fullClientPropertyKey + "." + CLIENT_ID_PROPERTY)) {
+			Set<String> registrationIds = getRegistrationIds(this.environment);
+			for (String registrationId : registrationIds) {
+				String fullRegistrationId = REGISTRATIONS_PROPERTY_PREFIX + "." + registrationId;
+				if (!this.environment.containsProperty(fullRegistrationId + "." + CLIENT_ID_PROPERTY)) {
 					continue;
 				}
 				ClientRegistrationProperties clientRegistrationProperties = binder.bind(
-					fullClientPropertyKey, Bindable.of(ClientRegistrationProperties.class)).get();
+					fullRegistrationId, Bindable.of(ClientRegistrationProperties.class)).get();
+				clientRegistrationProperties.setRegistrationId(registrationId);
 				ClientRegistration clientRegistration = new ClientRegistration.Builder(clientRegistrationProperties).build();
 				clientRegistrations.add(clientRegistration);
 			}
@@ -95,10 +109,10 @@ public class ClientRegistrationAutoConfiguration {
 		}
 	}
 
-	static Set<String> resolveClientPropertyKeys(Environment environment) {
+	static Set<String> getRegistrationIds(Environment environment) {
 		Binder binder = Binder.get(environment);
 		BindResult<Map<String, Object>> result = binder.bind(
-			CLIENT_PROPERTY_PREFIX, Bindable.mapOf(String.class, Object.class));
+			REGISTRATIONS_PROPERTY_PREFIX, Bindable.mapOf(String.class, Object.class));
 		return result.get().keySet();
 	}
 
@@ -112,10 +126,10 @@ public class ClientRegistrationAutoConfiguration {
 		@Override
 		public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
 			ConditionMessage.Builder message = ConditionMessage.forCondition("OAuth2 Client Properties");
-			Set<String> clientPropertyKeys = resolveClientPropertyKeys(context.getEnvironment());
-			if (!CollectionUtils.isEmpty(clientPropertyKeys)) {
+			Set<String> registrationIds = getRegistrationIds(context.getEnvironment());
+			if (!CollectionUtils.isEmpty(registrationIds)) {
 				return ConditionOutcome.match(message.foundExactly("OAuth2 Client(s) -> " +
-					clientPropertyKeys.stream().collect(Collectors.joining(", "))));
+					registrationIds.stream().collect(Collectors.joining(", "))));
 			}
 			return ConditionOutcome.noMatch(message.notAvailable("OAuth2 Client(s)"));
 		}

+ 37 - 40
samples/boot/oauth2login/src/main/resources/META-INF/oauth2-clients-defaults.yml

@@ -1,43 +1,40 @@
 security:
   oauth2:
     client:
-      google:
-        client-authentication-method: basic
-        authorization-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}"
-        scope: openid, profile, email, address, phone
-        authorization-uri: "https://accounts.google.com/o/oauth2/v2/auth"
-        token-uri: "https://www.googleapis.com/oauth2/v4/token"
-        user-info-uri: "https://www.googleapis.com/oauth2/v3/userinfo"
-        jwk-set-uri: "https://www.googleapis.com/oauth2/v3/certs"
-        client-name: Google
-        client-alias: google
-      github:
-        client-authentication-method: basic
-        authorization-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}"
-        scope: user
-        authorization-uri: "https://github.com/login/oauth/authorize"
-        token-uri: "https://github.com/login/oauth/access_token"
-        user-info-uri: "https://api.github.com/user"
-        user-name-attribute-name: "name"
-        client-name: GitHub
-        client-alias: github
-      facebook:
-        client-authentication-method: post
-        authorization-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}"
-        scope: public_profile, email
-        authorization-uri: "https://www.facebook.com/v2.8/dialog/oauth"
-        token-uri: "https://graph.facebook.com/v2.8/oauth/access_token"
-        user-info-uri: "https://graph.facebook.com/me"
-        user-name-attribute-name: "name"
-        client-name: Facebook
-        client-alias: facebook
-      okta:
-        client-authentication-method: basic
-        authorization-grant-type: authorization_code
-        redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{clientAlias}"
-        scope: openid, profile, email, address, phone
-        client-name: Okta
-        client-alias: okta
+      registrations:
+        google:
+          client-authentication-method: basic
+          authorization-grant-type: authorization_code
+          redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}"
+          scope: openid, profile, email, address, phone
+          authorization-uri: "https://accounts.google.com/o/oauth2/v2/auth"
+          token-uri: "https://www.googleapis.com/oauth2/v4/token"
+          user-info-uri: "https://www.googleapis.com/oauth2/v3/userinfo"
+          jwk-set-uri: "https://www.googleapis.com/oauth2/v3/certs"
+          client-name: Google
+        github:
+          client-authentication-method: basic
+          authorization-grant-type: authorization_code
+          redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}"
+          scope: user
+          authorization-uri: "https://github.com/login/oauth/authorize"
+          token-uri: "https://github.com/login/oauth/access_token"
+          user-info-uri: "https://api.github.com/user"
+          user-name-attribute-name: "name"
+          client-name: GitHub
+        facebook:
+          client-authentication-method: post
+          authorization-grant-type: authorization_code
+          redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}"
+          scope: public_profile, email
+          authorization-uri: "https://www.facebook.com/v2.8/dialog/oauth"
+          token-uri: "https://graph.facebook.com/v2.8/oauth/access_token"
+          user-info-uri: "https://graph.facebook.com/me"
+          user-name-attribute-name: "name"
+          client-name: Facebook
+        okta:
+          client-authentication-method: basic
+          authorization-grant-type: authorization_code
+          redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}"
+          scope: openid, profile, email, address, phone
+          client-name: Okta

+ 17 - 16
samples/boot/oauth2login/src/main/resources/application.yml

@@ -15,19 +15,20 @@ spring:
 security:
   oauth2:
     client:
-      google:
-        client-id: your-app-client-id
-        client-secret: your-app-client-secret
-      github:
-        client-id: your-app-client-id
-        client-secret: your-app-client-secret
-      facebook:
-        client-id: your-app-client-id
-        client-secret: your-app-client-secret
-      okta:
-        client-id: your-app-client-id
-        client-secret: your-app-client-secret
-        authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
-        token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
-        user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
-        jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
+      registrations:
+        google:
+          client-id: your-app-client-id
+          client-secret: your-app-client-secret
+        github:
+          client-id: your-app-client-id
+          client-secret: your-app-client-secret
+        facebook:
+          client-id: your-app-client-id
+          client-secret: your-app-client-secret
+        okta:
+          client-id: your-app-client-id
+          client-secret: your-app-client-secret
+          authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
+          token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
+          user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
+          jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys