Browse Source

Remove OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME

Closes gh-829
Joe Grandja 3 years ago
parent
commit
0656fde051
21 changed files with 115 additions and 63 deletions
  1. 10 0
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/authorization/Authorization.java
  2. 2 0
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/authorization/JpaOAuth2AuthorizationService.java
  3. 15 2
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/JdbcOAuth2AuthorizationService.java
  4. 35 9
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2Authorization.java
  5. 1 1
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java
  6. 2 2
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java
  7. 1 1
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java
  8. 1 1
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java
  9. 1 1
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java
  10. 5 3
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2TokenContext.java
  11. 1 0
      oauth2-authorization-server/src/main/resources/org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql
  12. 14 1
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/JdbcOAuth2AuthorizationServiceTests.java
  13. 2 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/TestOAuth2Authorizations.java
  14. 9 15
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java
  15. 3 7
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java
  16. 3 7
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java
  17. 5 8
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java
  18. 2 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java
  19. 1 1
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGeneratorTests.java
  20. 1 0
      oauth2-authorization-server/src/test/resources/org/springframework/security/oauth2/server/authorization/custom-oauth2-authorization-schema-clob-data-type.sql
  21. 1 0
      oauth2-authorization-server/src/test/resources/org/springframework/security/oauth2/server/authorization/custom-oauth2-authorization-schema.sql

+ 10 - 0
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/authorization/Authorization.java

@@ -31,6 +31,8 @@ public class Authorization {
 	private String registeredClientId;
 	private String registeredClientId;
 	private String principalName;
 	private String principalName;
 	private String authorizationGrantType;
 	private String authorizationGrantType;
+	@Column(length = 1000)
+	private String authorizedScopes;
 	@Column(length = 4000)
 	@Column(length = 4000)
 	private String attributes;
 	private String attributes;
 	@Column(length = 500)
 	@Column(length = 500)
@@ -101,6 +103,14 @@ public class Authorization {
 		this.authorizationGrantType = authorizationGrantType;
 		this.authorizationGrantType = authorizationGrantType;
 	}
 	}
 
 
+	public String getAuthorizedScopes() {
+		return this.authorizedScopes;
+	}
+
+	public void setAuthorizedScopes(String authorizedScopes) {
+		this.authorizedScopes = authorizedScopes;
+	}
+
 	public String getAttributes() {
 	public String getAttributes() {
 		return attributes;
 		return attributes;
 	}
 	}

+ 2 - 0
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/authorization/JpaOAuth2AuthorizationService.java

@@ -115,6 +115,7 @@ public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService
 				.id(entity.getId())
 				.id(entity.getId())
 				.principalName(entity.getPrincipalName())
 				.principalName(entity.getPrincipalName())
 				.authorizationGrantType(resolveAuthorizationGrantType(entity.getAuthorizationGrantType()))
 				.authorizationGrantType(resolveAuthorizationGrantType(entity.getAuthorizationGrantType()))
+				.authorizedScopes(StringUtils.commaDelimitedListToSet(entity.getAuthorizedScopes()))
 				.attributes(attributes -> attributes.putAll(parseMap(entity.getAttributes())));
 				.attributes(attributes -> attributes.putAll(parseMap(entity.getAttributes())));
 		if (entity.getState() != null) {
 		if (entity.getState() != null) {
 			builder.attribute(OAuth2ParameterNames.STATE, entity.getState());
 			builder.attribute(OAuth2ParameterNames.STATE, entity.getState());
@@ -164,6 +165,7 @@ public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService
 		entity.setRegisteredClientId(authorization.getRegisteredClientId());
 		entity.setRegisteredClientId(authorization.getRegisteredClientId());
 		entity.setPrincipalName(authorization.getPrincipalName());
 		entity.setPrincipalName(authorization.getPrincipalName());
 		entity.setAuthorizationGrantType(authorization.getAuthorizationGrantType().getValue());
 		entity.setAuthorizationGrantType(authorization.getAuthorizationGrantType().getValue());
+		entity.setAuthorizedScopes(StringUtils.collectionToDelimitedString(authorization.getAuthorizedScopes(), ","));
 		entity.setAttributes(writeMap(authorization.getAttributes()));
 		entity.setAttributes(writeMap(authorization.getAttributes()));
 		entity.setState(authorization.getAttribute(OAuth2ParameterNames.STATE));
 		entity.setState(authorization.getAttribute(OAuth2ParameterNames.STATE));
 
 

+ 15 - 2
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/JdbcOAuth2AuthorizationService.java

@@ -85,6 +85,7 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
 			+ "registered_client_id, "
 			+ "registered_client_id, "
 			+ "principal_name, "
 			+ "principal_name, "
 			+ "authorization_grant_type, "
 			+ "authorization_grant_type, "
+			+ "authorized_scopes, "
 			+ "attributes, "
 			+ "attributes, "
 			+ "state, "
 			+ "state, "
 			+ "authorization_code_value, "
 			+ "authorization_code_value, "
@@ -126,12 +127,12 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
 
 
 	// @formatter:off
 	// @formatter:off
 	private static final String SAVE_AUTHORIZATION_SQL = "INSERT INTO " + TABLE_NAME
 	private static final String SAVE_AUTHORIZATION_SQL = "INSERT INTO " + TABLE_NAME
-			+ " (" + COLUMN_NAMES + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+			+ " (" + COLUMN_NAMES + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
 	// @formatter:on
 	// @formatter:on
 
 
 	// @formatter:off
 	// @formatter:off
 	private static final String UPDATE_AUTHORIZATION_SQL = "UPDATE " + TABLE_NAME
 	private static final String UPDATE_AUTHORIZATION_SQL = "UPDATE " + TABLE_NAME
-			+ " SET registered_client_id = ?, principal_name = ?, authorization_grant_type = ?, attributes = ?, state = ?,"
+			+ " SET registered_client_id = ?, principal_name = ?, authorization_grant_type = ?, authorized_scopes = ?, attributes = ?, state = ?,"
 			+ " authorization_code_value = ?, authorization_code_issued_at = ?, authorization_code_expires_at = ?, authorization_code_metadata = ?,"
 			+ " authorization_code_value = ?, authorization_code_issued_at = ?, authorization_code_expires_at = ?, authorization_code_metadata = ?,"
 			+ " access_token_value = ?, access_token_issued_at = ?, access_token_expires_at = ?, access_token_metadata = ?, access_token_type = ?, access_token_scopes = ?,"
 			+ " access_token_value = ?, access_token_issued_at = ?, access_token_expires_at = ?, access_token_metadata = ?, access_token_type = ?, access_token_scopes = ?,"
 			+ " oidc_id_token_value = ?, oidc_id_token_issued_at = ?, oidc_id_token_expires_at = ?, oidc_id_token_metadata = ?,"
 			+ " oidc_id_token_value = ?, oidc_id_token_issued_at = ?, oidc_id_token_expires_at = ?, oidc_id_token_metadata = ?,"
@@ -342,11 +343,17 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
 			String id = rs.getString("id");
 			String id = rs.getString("id");
 			String principalName = rs.getString("principal_name");
 			String principalName = rs.getString("principal_name");
 			String authorizationGrantType = rs.getString("authorization_grant_type");
 			String authorizationGrantType = rs.getString("authorization_grant_type");
+			Set<String> authorizedScopes = Collections.emptySet();
+			String authorizedScopesString = rs.getString("authorized_scopes");
+			if (authorizedScopesString != null) {
+				authorizedScopes = StringUtils.commaDelimitedListToSet(authorizedScopesString);
+			}
 			Map<String, Object> attributes = parseMap(getLobValue(rs, "attributes"));
 			Map<String, Object> attributes = parseMap(getLobValue(rs, "attributes"));
 
 
 			builder.id(id)
 			builder.id(id)
 					.principalName(principalName)
 					.principalName(principalName)
 					.authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
 					.authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
+					.authorizedScopes(authorizedScopes)
 					.attributes((attrs) -> attrs.putAll(attributes));
 					.attributes((attrs) -> attrs.putAll(attributes));
 
 
 			String state = rs.getString("state");
 			String state = rs.getString("state");
@@ -485,6 +492,12 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
 			parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getPrincipalName()));
 			parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getPrincipalName()));
 			parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getAuthorizationGrantType().getValue()));
 			parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getAuthorizationGrantType().getValue()));
 
 
+			String authorizedScopes = null;
+			if (!CollectionUtils.isEmpty(authorization.getAuthorizedScopes())) {
+				authorizedScopes = StringUtils.collectionToDelimitedString(authorization.getAuthorizedScopes(), ",");
+			}
+			parameters.add(new SqlParameterValue(Types.VARCHAR, authorizedScopes));
+
 			String attributes = writeMap(authorization.getAttributes());
 			String attributes = writeMap(authorization.getAttributes());
 			parameters.add(mapToSqlParameter("attributes", attributes));
 			parameters.add(mapToSqlParameter("attributes", attributes));
 
 

+ 35 - 9
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2Authorization.java

@@ -19,8 +19,10 @@ import java.io.Serializable;
 import java.time.Instant;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
+import java.util.Set;
 import java.util.UUID;
 import java.util.UUID;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
 
 
@@ -51,18 +53,11 @@ import org.springframework.util.StringUtils;
  */
  */
 public class OAuth2Authorization implements Serializable {
 public class OAuth2Authorization implements Serializable {
 	private static final long serialVersionUID = SpringAuthorizationServerVersion.SERIAL_VERSION_UID;
 	private static final long serialVersionUID = SpringAuthorizationServerVersion.SERIAL_VERSION_UID;
-
-	/**
-	 * The name of the {@link #getAttribute(String) attribute} used for the authorized scope(s).
-	 * The value of the attribute is of type {@code Set<String>}.
-	 */
-	public static final String AUTHORIZED_SCOPE_ATTRIBUTE_NAME =
-			OAuth2Authorization.class.getName().concat(".AUTHORIZED_SCOPE");
-
 	private String id;
 	private String id;
 	private String registeredClientId;
 	private String registeredClientId;
 	private String principalName;
 	private String principalName;
 	private AuthorizationGrantType authorizationGrantType;
 	private AuthorizationGrantType authorizationGrantType;
+	private Set<String> authorizedScopes;
 	private Map<Class<? extends OAuth2Token>, Token<?>> tokens;
 	private Map<Class<? extends OAuth2Token>, Token<?>> tokens;
 	private Map<String, Object> attributes;
 	private Map<String, Object> attributes;
 
 
@@ -105,6 +100,16 @@ public class OAuth2Authorization implements Serializable {
 		return this.authorizationGrantType;
 		return this.authorizationGrantType;
 	}
 	}
 
 
+	/**
+	 * Returns the authorized scope(s).
+	 *
+	 * @return the {@code Set} of authorized scope(s)
+	 * @since 0.4.0
+	 */
+	public Set<String> getAuthorizedScopes() {
+		return this.authorizedScopes;
+	}
+
 	/**
 	/**
 	 * Returns the {@link Token} of type {@link OAuth2AccessToken}.
 	 * Returns the {@link Token} of type {@link OAuth2AccessToken}.
 	 *
 	 *
@@ -194,6 +199,7 @@ public class OAuth2Authorization implements Serializable {
 				Objects.equals(this.registeredClientId, that.registeredClientId) &&
 				Objects.equals(this.registeredClientId, that.registeredClientId) &&
 				Objects.equals(this.principalName, that.principalName) &&
 				Objects.equals(this.principalName, that.principalName) &&
 				Objects.equals(this.authorizationGrantType, that.authorizationGrantType) &&
 				Objects.equals(this.authorizationGrantType, that.authorizationGrantType) &&
+				Objects.equals(this.authorizedScopes, that.authorizedScopes) &&
 				Objects.equals(this.tokens, that.tokens) &&
 				Objects.equals(this.tokens, that.tokens) &&
 				Objects.equals(this.attributes, that.attributes);
 				Objects.equals(this.attributes, that.attributes);
 	}
 	}
@@ -201,7 +207,7 @@ public class OAuth2Authorization implements Serializable {
 	@Override
 	@Override
 	public int hashCode() {
 	public int hashCode() {
 		return Objects.hash(this.id, this.registeredClientId, this.principalName,
 		return Objects.hash(this.id, this.registeredClientId, this.principalName,
-				this.authorizationGrantType, this.tokens, this.attributes);
+				this.authorizationGrantType, this.authorizedScopes, this.tokens, this.attributes);
 	}
 	}
 
 
 	/**
 	/**
@@ -227,6 +233,7 @@ public class OAuth2Authorization implements Serializable {
 				.id(authorization.getId())
 				.id(authorization.getId())
 				.principalName(authorization.getPrincipalName())
 				.principalName(authorization.getPrincipalName())
 				.authorizationGrantType(authorization.getAuthorizationGrantType())
 				.authorizationGrantType(authorization.getAuthorizationGrantType())
+				.authorizedScopes(authorization.getAuthorizedScopes())
 				.tokens(authorization.tokens)
 				.tokens(authorization.tokens)
 				.attributes(attrs -> attrs.putAll(authorization.getAttributes()));
 				.attributes(attrs -> attrs.putAll(authorization.getAttributes()));
 	}
 	}
@@ -380,6 +387,7 @@ public class OAuth2Authorization implements Serializable {
 		private final String registeredClientId;
 		private final String registeredClientId;
 		private String principalName;
 		private String principalName;
 		private AuthorizationGrantType authorizationGrantType;
 		private AuthorizationGrantType authorizationGrantType;
+		private Set<String> authorizedScopes;
 		private Map<Class<? extends OAuth2Token>, Token<?>> tokens = new HashMap<>();
 		private Map<Class<? extends OAuth2Token>, Token<?>> tokens = new HashMap<>();
 		private final Map<String, Object> attributes = new HashMap<>();
 		private final Map<String, Object> attributes = new HashMap<>();
 
 
@@ -420,6 +428,18 @@ public class OAuth2Authorization implements Serializable {
 			return this;
 			return this;
 		}
 		}
 
 
+		/**
+		 * Sets the authorized scope(s).
+		 *
+		 * @param authorizedScopes the {@code Set} of authorized scope(s)
+		 * @return the {@link Builder}
+		 * @since 0.4.0
+		 */
+		public Builder authorizedScopes(Set<String> authorizedScopes) {
+			this.authorizedScopes = authorizedScopes;
+			return this;
+		}
+
 		/**
 		/**
 		 * Sets the {@link OAuth2AccessToken access token}.
 		 * Sets the {@link OAuth2AccessToken access token}.
 		 *
 		 *
@@ -522,6 +542,12 @@ public class OAuth2Authorization implements Serializable {
 			authorization.registeredClientId = this.registeredClientId;
 			authorization.registeredClientId = this.registeredClientId;
 			authorization.principalName = this.principalName;
 			authorization.principalName = this.principalName;
 			authorization.authorizationGrantType = this.authorizationGrantType;
 			authorization.authorizationGrantType = this.authorizationGrantType;
+			authorization.authorizedScopes =
+					Collections.unmodifiableSet(
+							!CollectionUtils.isEmpty(this.authorizedScopes) ?
+									new HashSet<>(this.authorizedScopes) :
+									new HashSet<>()
+					);
 			authorization.tokens = Collections.unmodifiableMap(this.tokens);
 			authorization.tokens = Collections.unmodifiableMap(this.tokens);
 			authorization.attributes = Collections.unmodifiableMap(this.attributes);
 			authorization.attributes = Collections.unmodifiableMap(this.attributes);
 			return authorization;
 			return authorization;

+ 1 - 1
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java

@@ -134,7 +134,7 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth
 				.principal(authorization.getAttribute(Principal.class.getName()))
 				.principal(authorization.getAttribute(Principal.class.getName()))
 				.providerContext(ProviderContextHolder.getProviderContext())
 				.providerContext(ProviderContextHolder.getProviderContext())
 				.authorization(authorization)
 				.authorization(authorization)
-				.authorizedScopes(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME))
+				.authorizedScopes(authorization.getAuthorizedScopes())
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrant(authorizationCodeAuthentication);
 				.authorizationGrant(authorizationCodeAuthentication);
 		// @formatter:on
 		// @formatter:on

+ 2 - 2
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java

@@ -265,8 +265,8 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen
 		}
 		}
 
 
 		OAuth2Authorization authorization = authorizationBuilder(registeredClient, principal, authorizationRequest)
 		OAuth2Authorization authorization = authorizationBuilder(registeredClient, principal, authorizationRequest)
+				.authorizedScopes(authorizationRequest.getScopes())
 				.token(authorizationCode)
 				.token(authorizationCode)
-				.attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizationRequest.getScopes())
 				.build();
 				.build();
 		this.authorizationService.save(authorization);
 		this.authorizationService.save(authorization);
 
 
@@ -392,10 +392,10 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen
 		}
 		}
 
 
 		OAuth2Authorization updatedAuthorization = OAuth2Authorization.from(authorization)
 		OAuth2Authorization updatedAuthorization = OAuth2Authorization.from(authorization)
+				.authorizedScopes(authorizedScopes)
 				.token(authorizationCode)
 				.token(authorizationCode)
 				.attributes(attrs -> {
 				.attributes(attrs -> {
 					attrs.remove(OAuth2ParameterNames.STATE);
 					attrs.remove(OAuth2ParameterNames.STATE);
-					attrs.put(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizedScopes);
 				})
 				})
 				.build();
 				.build();
 		this.authorizationService.save(updatedAuthorization);
 		this.authorizationService.save(updatedAuthorization);

+ 1 - 1
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java

@@ -123,7 +123,7 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth
 		OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
 		OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
 				.principalName(clientPrincipal.getName())
 				.principalName(clientPrincipal.getName())
 				.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
 				.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
-				.attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizedScopes);
+				.authorizedScopes(authorizedScopes);
 		// @formatter:on
 		// @formatter:on
 		if (generatedAccessToken instanceof ClaimAccessor) {
 		if (generatedAccessToken instanceof ClaimAccessor) {
 			authorizationBuilder.token(accessToken, (metadata) ->
 			authorizationBuilder.token(accessToken, (metadata) ->

+ 1 - 1
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java

@@ -118,7 +118,7 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic
 		// The requested scope MUST NOT include any scope not originally granted by the resource owner,
 		// The requested scope MUST NOT include any scope not originally granted by the resource owner,
 		// and if omitted is treated as equal to the scope originally granted by the resource owner.
 		// and if omitted is treated as equal to the scope originally granted by the resource owner.
 		Set<String> scopes = refreshTokenAuthentication.getScopes();
 		Set<String> scopes = refreshTokenAuthentication.getScopes();
-		Set<String> authorizedScopes = authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME);
+		Set<String> authorizedScopes = authorization.getAuthorizedScopes();
 		if (!authorizedScopes.containsAll(scopes)) {
 		if (!authorizedScopes.containsAll(scopes)) {
 			throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_SCOPE);
 			throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_SCOPE);
 		}
 		}

+ 1 - 1
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java

@@ -233,7 +233,7 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe
 		OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
 		OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
 				.principalName(registeredClient.getClientId())
 				.principalName(registeredClient.getClientId())
 				.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
 				.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
-				.attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizedScopes);
+				.authorizedScopes(authorizedScopes);
 		// @formatter:on
 		// @formatter:on
 		if (registrationAccessToken instanceof ClaimAccessor) {
 		if (registrationAccessToken instanceof ClaimAccessor) {
 			authorizationBuilder.token(accessToken, (metadata) ->
 			authorizationBuilder.token(accessToken, (metadata) ->

+ 5 - 3
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2TokenContext.java

@@ -88,8 +88,8 @@ public interface OAuth2TokenContext extends Context {
 	 * @return the authorized scope(s)
 	 * @return the authorized scope(s)
 	 */
 	 */
 	default Set<String> getAuthorizedScopes() {
 	default Set<String> getAuthorizedScopes() {
-		return hasKey(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME) ?
-				get(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME) :
+		return hasKey(AbstractBuilder.AUTHORIZED_SCOPE_KEY) ?
+				get(AbstractBuilder.AUTHORIZED_SCOPE_KEY) :
 				Collections.emptySet();
 				Collections.emptySet();
 	}
 	}
 
 
@@ -130,6 +130,8 @@ public interface OAuth2TokenContext extends Context {
 	abstract class AbstractBuilder<T extends OAuth2TokenContext, B extends AbstractBuilder<T, B>> {
 	abstract class AbstractBuilder<T extends OAuth2TokenContext, B extends AbstractBuilder<T, B>> {
 		private static final String PRINCIPAL_AUTHENTICATION_KEY =
 		private static final String PRINCIPAL_AUTHENTICATION_KEY =
 				Authentication.class.getName().concat(".PRINCIPAL");
 				Authentication.class.getName().concat(".PRINCIPAL");
+		private static final String AUTHORIZED_SCOPE_KEY =
+				OAuth2Authorization.class.getName().concat(".AUTHORIZED_SCOPE");
 		private static final String AUTHORIZATION_GRANT_AUTHENTICATION_KEY =
 		private static final String AUTHORIZATION_GRANT_AUTHENTICATION_KEY =
 				Authentication.class.getName().concat(".AUTHORIZATION_GRANT");
 				Authentication.class.getName().concat(".AUTHORIZATION_GRANT");
 		private final Map<Object, Object> context = new HashMap<>();
 		private final Map<Object, Object> context = new HashMap<>();
@@ -182,7 +184,7 @@ public interface OAuth2TokenContext extends Context {
 		 * @return the {@link AbstractBuilder} for further configuration
 		 * @return the {@link AbstractBuilder} for further configuration
 		 */
 		 */
 		public B authorizedScopes(Set<String> authorizedScopes) {
 		public B authorizedScopes(Set<String> authorizedScopes) {
-			return put(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizedScopes);
+			return put(AUTHORIZED_SCOPE_KEY, authorizedScopes);
 		}
 		}
 
 
 		/**
 		/**

+ 1 - 0
oauth2-authorization-server/src/main/resources/org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql

@@ -8,6 +8,7 @@ CREATE TABLE oauth2_authorization (
     registered_client_id varchar(100) NOT NULL,
     registered_client_id varchar(100) NOT NULL,
     principal_name varchar(200) NOT NULL,
     principal_name varchar(200) NOT NULL,
     authorization_grant_type varchar(100) NOT NULL,
     authorization_grant_type varchar(100) NOT NULL,
+    authorized_scopes varchar(1000) DEFAULT NULL,
     attributes blob DEFAULT NULL,
     attributes blob DEFAULT NULL,
     state varchar(500) DEFAULT NULL,
     state varchar(500) DEFAULT NULL,
     authorization_code_value blob DEFAULT NULL,
     authorization_code_value blob DEFAULT NULL,

+ 14 - 1
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/JdbcOAuth2AuthorizationServiceTests.java

@@ -467,6 +467,7 @@ public class JdbcOAuth2AuthorizationServiceTests {
 				+ "registeredClientId, "
 				+ "registeredClientId, "
 				+ "principalName, "
 				+ "principalName, "
 				+ "authorizationGrantType, "
 				+ "authorizationGrantType, "
+				+ "authorizedScopes, "
 				+ "attributes, "
 				+ "attributes, "
 				+ "state, "
 				+ "state, "
 				+ "authorizationCodeValue, "
 				+ "authorizationCodeValue, "
@@ -503,7 +504,7 @@ public class JdbcOAuth2AuthorizationServiceTests {
 
 
 		// @formatter:off
 		// @formatter:off
 		private static final String SAVE_AUTHORIZATION_SQL = "INSERT INTO " + TABLE_NAME
 		private static final String SAVE_AUTHORIZATION_SQL = "INSERT INTO " + TABLE_NAME
-				+ " (" + COLUMN_NAMES + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+				+ " (" + COLUMN_NAMES + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
 		// @formatter:on
 		// @formatter:on
 
 
 		private static final String REMOVE_AUTHORIZATION_SQL = "DELETE FROM " + TABLE_NAME + " WHERE " + PK_FILTER;
 		private static final String REMOVE_AUTHORIZATION_SQL = "DELETE FROM " + TABLE_NAME + " WHERE " + PK_FILTER;
@@ -567,11 +568,17 @@ public class JdbcOAuth2AuthorizationServiceTests {
 				String id = rs.getString("id");
 				String id = rs.getString("id");
 				String principalName = rs.getString("principalName");
 				String principalName = rs.getString("principalName");
 				String authorizationGrantType = rs.getString("authorizationGrantType");
 				String authorizationGrantType = rs.getString("authorizationGrantType");
+				Set<String> authorizedScopes = Collections.emptySet();
+				String authorizedScopesString = rs.getString("authorizedScopes");
+				if (authorizedScopesString != null) {
+					authorizedScopes = StringUtils.commaDelimitedListToSet(authorizedScopesString);
+				}
 				Map<String, Object> attributes = parseMap(rs.getString("attributes"));
 				Map<String, Object> attributes = parseMap(rs.getString("attributes"));
 
 
 				builder.id(id)
 				builder.id(id)
 						.principalName(principalName)
 						.principalName(principalName)
 						.authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
 						.authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
+						.authorizedScopes(authorizedScopes)
 						.attributes((attrs) -> attrs.putAll(attributes));
 						.attributes((attrs) -> attrs.putAll(attributes));
 
 
 				String state = rs.getString("state");
 				String state = rs.getString("state");
@@ -660,6 +667,12 @@ public class JdbcOAuth2AuthorizationServiceTests {
 				parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getPrincipalName()));
 				parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getPrincipalName()));
 				parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getAuthorizationGrantType().getValue()));
 				parameters.add(new SqlParameterValue(Types.VARCHAR, authorization.getAuthorizationGrantType().getValue()));
 
 
+				String authorizedScopes = null;
+				if (!CollectionUtils.isEmpty(authorization.getAuthorizedScopes())) {
+					authorizedScopes = StringUtils.collectionToDelimitedString(authorization.getAuthorizedScopes(), ",");
+				}
+				parameters.add(new SqlParameterValue(Types.VARCHAR, authorizedScopes));
+
 				String attributes = writeMap(authorization.getAttributes());
 				String attributes = writeMap(authorization.getAttributes());
 				parameters.add(new SqlParameterValue(Types.VARCHAR, attributes));
 				parameters.add(new SqlParameterValue(Types.VARCHAR, attributes));
 
 

+ 2 - 2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/TestOAuth2Authorizations.java

@@ -82,12 +82,12 @@ public class TestOAuth2Authorizations {
 				.id("id")
 				.id("id")
 				.principalName("principal")
 				.principalName("principal")
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.authorizedScopes(authorizationRequest.getScopes())
 				.token(authorizationCode)
 				.token(authorizationCode)
 				.attribute(OAuth2ParameterNames.STATE, "state")
 				.attribute(OAuth2ParameterNames.STATE, "state")
 				.attribute(OAuth2AuthorizationRequest.class.getName(), authorizationRequest)
 				.attribute(OAuth2AuthorizationRequest.class.getName(), authorizationRequest)
 				.attribute(Principal.class.getName(),
 				.attribute(Principal.class.getName(),
-						new TestingAuthenticationToken("principal", null, "ROLE_A", "ROLE_B"))
-				.attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizationRequest.getScopes());
+						new TestingAuthenticationToken("principal", null, "ROLE_A", "ROLE_B"));
 		if (accessToken != null) {
 		if (accessToken != null) {
 			OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(
 			OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(
 					"refresh-token", Instant.now(), Instant.now().plus(1, ChronoUnit.HOURS));
 					"refresh-token", Instant.now(), Instant.now().plus(1, ChronoUnit.HOURS));

+ 9 - 15
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java

@@ -409,8 +409,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(jwtEncodingContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(jwtEncodingContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
 		assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
-		assertThat(jwtEncodingContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(jwtEncodingContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -422,7 +421,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
 		JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
 
 
 		Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
 		Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
-		assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(scopes).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName());
 		assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName());
 
 
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
@@ -432,8 +431,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
 		assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken());
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken());
-		assertThat(accessTokenAuthentication.getAccessToken().getScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(accessTokenAuthentication.getRefreshToken()).isNotNull();
 		assertThat(accessTokenAuthentication.getRefreshToken()).isNotNull();
 		assertThat(accessTokenAuthentication.getRefreshToken()).isEqualTo(updatedAuthorization.getRefreshToken().getToken());
 		assertThat(accessTokenAuthentication.getRefreshToken()).isEqualTo(updatedAuthorization.getRefreshToken().getToken());
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
@@ -469,8 +467,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(accessTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(accessTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(accessTokenContext.getAuthorization()).isEqualTo(authorization);
 		assertThat(accessTokenContext.getAuthorization()).isEqualTo(authorization);
 		assertThat(accessTokenContext.getAuthorization().getAccessToken()).isNull();
 		assertThat(accessTokenContext.getAuthorization().getAccessToken()).isNull();
-		assertThat(accessTokenContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(accessTokenContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(accessTokenContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(accessTokenContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(accessTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(accessTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(accessTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(accessTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -486,8 +483,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(idTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(idTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(idTokenContext.getAuthorization()).isNotEqualTo(authorization);
 		assertThat(idTokenContext.getAuthorization()).isNotEqualTo(authorization);
 		assertThat(idTokenContext.getAuthorization().getAccessToken()).isNotNull();
 		assertThat(idTokenContext.getAuthorization().getAccessToken()).isNotNull();
-		assertThat(idTokenContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(idTokenContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(idTokenContext.getTokenType().getValue()).isEqualTo(OidcParameterNames.ID_TOKEN);
 		assertThat(idTokenContext.getTokenType().getValue()).isEqualTo(OidcParameterNames.ID_TOKEN);
 		assertThat(idTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(idTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(idTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(idTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -503,7 +499,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
 		assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken());
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken());
-		Set<String> accessTokenScopes = new HashSet<>(updatedAuthorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		Set<String> accessTokenScopes = new HashSet<>(updatedAuthorization.getAuthorizedScopes());
 		assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(accessTokenScopes);
 		assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(accessTokenScopes);
 		assertThat(accessTokenAuthentication.getRefreshToken()).isNotNull();
 		assertThat(accessTokenAuthentication.getRefreshToken()).isNotNull();
 		assertThat(accessTokenAuthentication.getRefreshToken()).isEqualTo(updatedAuthorization.getRefreshToken().getToken());
 		assertThat(accessTokenAuthentication.getRefreshToken()).isEqualTo(updatedAuthorization.getRefreshToken().getToken());
@@ -543,8 +539,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(jwtEncodingContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(jwtEncodingContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
 		assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
-		assertThat(jwtEncodingContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(jwtEncodingContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
 		assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -556,7 +551,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
 		JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
 
 
 		Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
 		Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
-		assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(scopes).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName());
 		assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName());
 
 
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
@@ -566,8 +561,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
 		assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
 		assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken());
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken());
-		assertThat(accessTokenAuthentication.getAccessToken().getScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(accessTokenAuthentication.getRefreshToken()).isNull();
 		assertThat(accessTokenAuthentication.getRefreshToken()).isNull();
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
 		assertThat(authorizationCode.isInvalidated()).isTrue();
 		assertThat(authorizationCode.isInvalidated()).isTrue();

+ 3 - 7
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java

@@ -604,7 +604,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
 		assertThat(authorization.<Authentication>getAttribute(Principal.class.getName())).isEqualTo(this.principal);
 		assertThat(authorization.<Authentication>getAttribute(Principal.class.getName())).isEqualTo(this.principal);
 
 
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = authorization.getToken(OAuth2AuthorizationCode.class);
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = authorization.getToken(OAuth2AuthorizationCode.class);
-		Set<String> authorizedScopes = authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME);
+		Set<String> authorizedScopes = authorization.getAuthorizedScopes();
 
 
 		assertThat(authenticationResult.getClientId()).isEqualTo(registeredClient.getClientId());
 		assertThat(authenticationResult.getClientId()).isEqualTo(registeredClient.getClientId());
 		assertThat(authenticationResult.getPrincipal()).isEqualTo(this.principal);
 		assertThat(authenticationResult.getPrincipal()).isEqualTo(this.principal);
@@ -875,8 +875,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
 		OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
 		assertThat(authorizationCode).isNotNull();
 		assertThat(authorizationCode).isNotNull();
 		assertThat(updatedAuthorization.<String>getAttribute(OAuth2ParameterNames.STATE)).isNull();
 		assertThat(updatedAuthorization.<String>getAttribute(OAuth2ParameterNames.STATE)).isNull();
-		assertThat(updatedAuthorization.<Set<String>>getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME))
-				.isEqualTo(authorizedScopes);
+		assertThat(updatedAuthorization.getAuthorizedScopes()).isEqualTo(authorizedScopes);
 
 
 		assertThat(authenticationResult.getClientId()).isEqualTo(registeredClient.getClientId());
 		assertThat(authenticationResult.getClientId()).isEqualTo(registeredClient.getClientId());
 		assertThat(authenticationResult.getPrincipal()).isEqualTo(this.principal);
 		assertThat(authenticationResult.getPrincipal()).isEqualTo(this.principal);
@@ -981,10 +980,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
 		verify(this.authorizationService).save(authorizationCaptor.capture());
 		verify(this.authorizationService).save(authorizationCaptor.capture());
 		OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
 		OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
-
-		assertThat(updatedAuthorization.<Set<String>>getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME))
-				.isEqualTo(requestedScopes);
-
+		assertThat(updatedAuthorization.getAuthorizedScopes()).isEqualTo(requestedScopes);
 		assertThat(authenticationResult.getScopes()).isEqualTo(requestedScopes);
 		assertThat(authenticationResult.getScopes()).isEqualTo(requestedScopes);
 	}
 	}
 
 

+ 3 - 7
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java

@@ -258,17 +258,13 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
 		ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
 		verify(this.authorizationService).save(authorizationCaptor.capture());
 		verify(this.authorizationService).save(authorizationCaptor.capture());
 		OAuth2Authorization authorization = authorizationCaptor.getValue();
 		OAuth2Authorization authorization = authorizationCaptor.getValue();
-
-		assertThat(jwtEncodingContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
-
+		assertThat(jwtEncodingContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(authorization.getRegisteredClientId()).isEqualTo(clientPrincipal.getRegisteredClient().getId());
 		assertThat(authorization.getRegisteredClientId()).isEqualTo(clientPrincipal.getRegisteredClient().getId());
 		assertThat(authorization.getPrincipalName()).isEqualTo(clientPrincipal.getName());
 		assertThat(authorization.getPrincipalName()).isEqualTo(clientPrincipal.getName());
 		assertThat(authorization.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
 		assertThat(authorization.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
 		assertThat(authorization.getAccessToken()).isNotNull();
 		assertThat(authorization.getAccessToken()).isNotNull();
-		assertThat(authorization.<Set<String>>getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)).isNotNull();
-		assertThat(authorization.getAccessToken().getToken().getScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(authorization.getAuthorizedScopes()).isNotNull();
+		assertThat(authorization.getAccessToken().getToken().getScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(authorization.getAccessToken().getToken());
 		assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(authorization.getAccessToken().getToken());
 	}
 	}

+ 5 - 8
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java

@@ -173,8 +173,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
 		assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(jwtEncodingContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(jwtEncodingContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
 		assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
-		assertThat(jwtEncodingContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(jwtEncodingContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
 		assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
 		assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -218,8 +217,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
 		assertThat(accessTokenContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(accessTokenContext.getRegisteredClient()).isEqualTo(registeredClient);
 		assertThat(accessTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(accessTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(accessTokenContext.getAuthorization()).isEqualTo(authorization);
 		assertThat(accessTokenContext.getAuthorization()).isEqualTo(authorization);
-		assertThat(accessTokenContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(accessTokenContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(accessTokenContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(accessTokenContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN);
 		assertThat(accessTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
 		assertThat(accessTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
 		assertThat(accessTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(accessTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -235,8 +233,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
 		assertThat(idTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(idTokenContext.<Authentication>getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName()));
 		assertThat(idTokenContext.getAuthorization()).isNotEqualTo(authorization);
 		assertThat(idTokenContext.getAuthorization()).isNotEqualTo(authorization);
 		assertThat(idTokenContext.getAuthorization().getAccessToken()).isNotEqualTo(authorization.getAccessToken());
 		assertThat(idTokenContext.getAuthorization().getAccessToken()).isNotEqualTo(authorization.getAccessToken());
-		assertThat(idTokenContext.getAuthorizedScopes())
-				.isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
+		assertThat(idTokenContext.getAuthorizedScopes()).isEqualTo(authorization.getAuthorizedScopes());
 		assertThat(idTokenContext.getTokenType().getValue()).isEqualTo(OidcParameterNames.ID_TOKEN);
 		assertThat(idTokenContext.getTokenType().getValue()).isEqualTo(OidcParameterNames.ID_TOKEN);
 		assertThat(idTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
 		assertThat(idTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
 		assertThat(idTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
 		assertThat(idTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
@@ -303,7 +300,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
 
 
 		OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
 		OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
 				registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
 				registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
-		Set<String> authorizedScopes = authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME);
+		Set<String> authorizedScopes = authorization.getAuthorizedScopes();
 		Set<String> requestedScopes = new HashSet<>(authorizedScopes);
 		Set<String> requestedScopes = new HashSet<>(authorizedScopes);
 		requestedScopes.remove("scope1");
 		requestedScopes.remove("scope1");
 		OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
 		OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
@@ -326,7 +323,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
 
 
 		OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
 		OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
 				registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
 				registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
-		Set<String> authorizedScopes = authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME);
+		Set<String> authorizedScopes = authorization.getAuthorizedScopes();
 		Set<String> requestedScopes = new HashSet<>(authorizedScopes);
 		Set<String> requestedScopes = new HashSet<>(authorizedScopes);
 		requestedScopes.add("unauthorized");
 		requestedScopes.add("unauthorized");
 		OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
 		OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(

+ 2 - 2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java

@@ -139,7 +139,7 @@ public class JwtGeneratorTests {
 				.principal(authorization.getAttribute(Principal.class.getName()))
 				.principal(authorization.getAttribute(Principal.class.getName()))
 				.providerContext(this.providerContext)
 				.providerContext(this.providerContext)
 				.authorization(authorization)
 				.authorization(authorization)
-				.authorizedScopes(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME))
+				.authorizedScopes(authorization.getAuthorizedScopes())
 				.tokenType(OAuth2TokenType.ACCESS_TOKEN)
 				.tokenType(OAuth2TokenType.ACCESS_TOKEN)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrant(authentication)
 				.authorizationGrant(authentication)
@@ -170,7 +170,7 @@ public class JwtGeneratorTests {
 				.principal(authorization.getAttribute(Principal.class.getName()))
 				.principal(authorization.getAttribute(Principal.class.getName()))
 				.providerContext(this.providerContext)
 				.providerContext(this.providerContext)
 				.authorization(authorization)
 				.authorization(authorization)
-				.authorizedScopes(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME))
+				.authorizedScopes(authorization.getAuthorizedScopes())
 				.tokenType(ID_TOKEN_TOKEN_TYPE)
 				.tokenType(ID_TOKEN_TOKEN_TYPE)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrant(authentication)
 				.authorizationGrant(authentication)

+ 1 - 1
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGeneratorTests.java

@@ -136,7 +136,7 @@ public class OAuth2AccessTokenGeneratorTests {
 				.principal(principal)
 				.principal(principal)
 				.providerContext(this.providerContext)
 				.providerContext(this.providerContext)
 				.authorization(authorization)
 				.authorization(authorization)
-				.authorizedScopes(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME))
+				.authorizedScopes(authorization.getAuthorizedScopes())
 				.tokenType(OAuth2TokenType.ACCESS_TOKEN)
 				.tokenType(OAuth2TokenType.ACCESS_TOKEN)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
 				.authorizationGrant(authentication)
 				.authorizationGrant(authentication)

+ 1 - 0
oauth2-authorization-server/src/test/resources/org/springframework/security/oauth2/server/authorization/custom-oauth2-authorization-schema-clob-data-type.sql

@@ -3,6 +3,7 @@ CREATE TABLE oauth2_authorization (
     registered_client_id varchar(100) NOT NULL,
     registered_client_id varchar(100) NOT NULL,
     principal_name varchar(200) NOT NULL,
     principal_name varchar(200) NOT NULL,
     authorization_grant_type varchar(100) NOT NULL,
     authorization_grant_type varchar(100) NOT NULL,
+    authorized_scopes varchar(1000) DEFAULT NULL,
     attributes varchar(4000) DEFAULT NULL,
     attributes varchar(4000) DEFAULT NULL,
     state varchar(500) DEFAULT NULL,
     state varchar(500) DEFAULT NULL,
     authorization_code_value clob DEFAULT NULL,
     authorization_code_value clob DEFAULT NULL,

+ 1 - 0
oauth2-authorization-server/src/test/resources/org/springframework/security/oauth2/server/authorization/custom-oauth2-authorization-schema.sql

@@ -3,6 +3,7 @@ CREATE TABLE oauth2Authorization (
     registeredClientId varchar(100) NOT NULL,
     registeredClientId varchar(100) NOT NULL,
     principalName varchar(200) NOT NULL,
     principalName varchar(200) NOT NULL,
     authorizationGrantType varchar(100) NOT NULL,
     authorizationGrantType varchar(100) NOT NULL,
+    authorizedScopes varchar(1000) DEFAULT NULL,
     attributes varchar(4000) DEFAULT NULL,
     attributes varchar(4000) DEFAULT NULL,
     state varchar(500) DEFAULT NULL,
     state varchar(500) DEFAULT NULL,
     authorizationCodeValue varchar(1000) DEFAULT NULL,
     authorizationCodeValue varchar(1000) DEFAULT NULL,