From 814742fef6b4b3ea5ee3236be613133b79951611 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 27 Sep 2017 09:14:55 -0400 Subject: [PATCH] Rename ClientRegistration.clientAlias -> registrationId Fixes gh-4575 --- .../oauth2/client/OAuth2LoginConfigurer.java | 10 +-- ...ecurity-oauth2-client-templates.properties | 8 +- .../registration/ClientRegistration.java | 47 +++++------ .../ClientRegistrationProperties.java | 17 ++-- .../ClientRegistrationRepository.java | 4 +- .../InMemoryClientRegistrationRepository.java | 10 +-- ... => RegistrationIdIdentifierStrategy.java} | 6 +- .../token/InMemoryAccessTokenRepository.java | 3 - ...ionCodeAuthenticationProcessingFilter.java | 12 +-- ...uthorizationCodeRequestRedirectFilter.java | 14 ++-- ...deAuthenticationProcessingFilterTests.java | 3 +- ...izationCodeRequestRedirectFilterTests.java | 5 +- .../security/oauth2/client/web/TestUtil.java | 12 +-- samples/boot/oauth2login/README.adoc | 67 ++++++++-------- .../samples/OAuth2LoginApplicationTests.java | 24 +++--- .../ClientRegistrationAutoConfiguration.java | 42 ++++++---- .../META-INF/oauth2-clients-defaults.yml | 77 +++++++++---------- .../src/main/resources/application.yml | 33 ++++---- 18 files changed, 198 insertions(+), 196 deletions(-) rename oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/{ClientAliasIdentifierStrategy.java => RegistrationIdIdentifierStrategy.java} (83%) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java index df018b3bbc..0e901dcae4 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java +++ b/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> 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> exten Map oauth2AuthenticationUrlToClientName = clientRegistrationRepository.getRegistrations().stream() .collect(Collectors.toMap( - e -> authorizationRequestBaseUri + "/" + e.getClientAlias(), + e -> authorizationRequestBaseUri + "/" + e.getRegistrationId(), e -> e.getClientName())); loginPageGeneratingFilter.setOauth2LoginEnabled(true); loginPageGeneratingFilter.setOauth2AuthenticationUrlToClientName(oauth2AuthenticationUrlToClientName); diff --git a/config/src/main/resources/org/springframework/security/config/oauth2/client/spring-security-oauth2-client-templates.properties b/config/src/main/resources/org/springframework/security/config/oauth2/client/spring-security-oauth2-client-templates.properties index 2e529e4393..b5ddea8857 100644 --- a/config/src/main/resources/org/springframework/security/config/oauth2/client/spring-security-oauth2-client-templates.properties +++ b/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 diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java index 449aa8ef0e..91323026fd 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java @@ -33,6 +33,7 @@ import java.util.Set; * @see Section 2 Client Registration */ 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 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"); } } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationProperties.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationProperties.java index 20ac915292..13aa02b453 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationProperties.java +++ b/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; - } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationRepository.java index ea4b406479..61c3c94d2d 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrationRepository.java +++ b/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 getRegistrationsByClientId(String clientId); + List findByClientId(String clientId); - ClientRegistration getRegistrationByClientAlias(String clientAlias); + ClientRegistration findByRegistrationId(String registrationId); List getRegistrations(); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java index 07b96bb392..5508075c59 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java +++ b/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 identifierStrategy = new ClientAliasIdentifierStrategy(); + private final ClientRegistrationIdentifierStrategy identifierStrategy = new RegistrationIdIdentifierStrategy(); private final Map registrations; public InMemoryClientRegistrationRepository(List registrations) { @@ -49,7 +49,7 @@ public final class InMemoryClientRegistrationRepository implements ClientRegistr } @Override - public List getRegistrationsByClientId(String clientId) { + public List 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); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientAliasIdentifierStrategy.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/RegistrationIdIdentifierStrategy.java similarity index 83% rename from oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientAliasIdentifierStrategy.java rename to oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/RegistrationIdIdentifierStrategy.java index 6894e9a52d..be56eb986f 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientAliasIdentifierStrategy.java +++ b/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 { +public class RegistrationIdIdentifierStrategy implements ClientRegistrationIdentifierStrategy { @Override public String getIdentifier(ClientRegistration clientRegistration) { Assert.notNull(clientRegistration, "clientRegistration cannot be null"); - return clientRegistration.getClientAlias(); + return clientRegistration.getRegistrationId(); } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java index e548c559d0..37e865b807 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java +++ b/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()); } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilter.java index 1864ed73ce..16e7a78c46 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilter.java +++ b/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); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java index 6cdf9c3289..265ee9362e 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java +++ b/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) diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java index 43ce706245..f06bf070b5 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java +++ b/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); diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java index b80eedee99..6a01fe598c 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java +++ b/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(); diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/TestUtil.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/TestUtil.java index d4624ae86b..626414b75c 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/TestUtil.java +++ b/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"); diff --git a/samples/boot/oauth2login/README.adoc b/samples/boot/oauth2login/README.adoc index 6fd0d739a0..ee4220e986 100644 --- a/samples/boot/oauth2login/README.adoc +++ b/samples/boot/oauth2login/README.adoc @@ -67,7 +67,7 @@ and have granted access to the OAuth Client _(created from the <> 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 <>. ==== @@ -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 <> 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 <>. ==== @@ -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 <> 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 <>. ==== @@ -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 <> 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 <>. ==== @@ -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 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(); } } diff --git a/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java b/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java index 5736c4d957..651e17a6ca 100644 --- a/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java +++ b/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 clientRegistrations = new ArrayList<>(); - Set clientPropertyKeys = resolveClientPropertyKeys(this.environment); - for (String clientPropertyKey : clientPropertyKeys) { - String fullClientPropertyKey = CLIENT_PROPERTY_PREFIX + "." + clientPropertyKey; - if (!this.environment.containsProperty(fullClientPropertyKey + "." + CLIENT_ID_PROPERTY)) { + Set 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 resolveClientPropertyKeys(Environment environment) { + static Set getRegistrationIds(Environment environment) { Binder binder = Binder.get(environment); BindResult> 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 clientPropertyKeys = resolveClientPropertyKeys(context.getEnvironment()); - if (!CollectionUtils.isEmpty(clientPropertyKeys)) { + Set 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)")); } diff --git a/samples/boot/oauth2login/src/main/resources/META-INF/oauth2-clients-defaults.yml b/samples/boot/oauth2login/src/main/resources/META-INF/oauth2-clients-defaults.yml index d05088e3de..223a7bd3ca 100644 --- a/samples/boot/oauth2login/src/main/resources/META-INF/oauth2-clients-defaults.yml +++ b/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 diff --git a/samples/boot/oauth2login/src/main/resources/application.yml b/samples/boot/oauth2login/src/main/resources/application.yml index 7b1420317f..7f7f1b23c4 100644 --- a/samples/boot/oauth2login/src/main/resources/application.yml +++ b/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