From fd9df9e2e7db681e4577abcf83f97f1eed688b0e Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 8 Feb 2021 20:33:17 -0500 Subject: [PATCH] Remove OAuth2AuthorizationAttributeNames.ACCESS_TOKEN_ATTRIBUTES Issue gh-213 --- .../authorization/OAuth2Authorization.java | 15 +++++++++ .../OAuth2AuthorizationAttributeNames.java | 6 ---- ...thorizationCodeAuthenticationProvider.java | 33 +++++++++++++------ ...ientCredentialsAuthenticationProvider.java | 14 +++++--- ...th2RefreshTokenAuthenticationProvider.java | 13 +++++--- 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2Authorization.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2Authorization.java index 5bf8f23..a5efa5a 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2Authorization.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2Authorization.java @@ -221,6 +221,11 @@ public class OAuth2Authorization implements Serializable { */ public static final String INVALIDATED_METADATA_NAME = TOKEN_METADATA_BASE.concat("invalidated"); + /** + * The name of the metadata used for the claims of the token. + */ + public static final String CLAIMS_METADATA_NAME = TOKEN_METADATA_BASE.concat("claims"); + private final T token; private final Map metadata; @@ -252,6 +257,16 @@ public class OAuth2Authorization implements Serializable { return Boolean.TRUE.equals(getMetadata(INVALIDATED_METADATA_NAME)); } + /** + * Returns the claims associated to the token. + * + * @return a {@code Map} of the claims, or {@code null} if not available + */ + @Nullable + public Map getClaims() { + return getMetadata(CLAIMS_METADATA_NAME); + } + /** * Returns the value of the metadata associated to the token. * diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationAttributeNames.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationAttributeNames.java index 0274736..08c1da7 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationAttributeNames.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationAttributeNames.java @@ -16,7 +16,6 @@ package org.springframework.security.oauth2.server.authorization; -import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; /** @@ -44,11 +43,6 @@ public interface OAuth2AuthorizationAttributeNames { */ String AUTHORIZED_SCOPES = OAuth2Authorization.class.getName().concat(".AUTHORIZED_SCOPES"); - /** - * The name of the attribute used for the attributes/claims of the {@link OAuth2AccessToken}. - */ - String ACCESS_TOKEN_ATTRIBUTES = OAuth2Authorization.class.getName().concat(".ACCESS_TOKEN_ATTRIBUTES"); - /** * The name of the attribute used for the resource owner {@code Principal}. */ diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java index 149fe3b..f83ac86 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java @@ -137,10 +137,11 @@ public class OAuth2AuthorizationCodeAuthenticationProvider implements Authentica JoseHeader headers = context.getHeaders().build(); JwtClaimsSet claims = context.getClaims().build(); - Jwt jwt = this.jwtEncoder.encode(headers, claims); + Jwt jwtAccessToken = this.jwtEncoder.encode(headers, claims); OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, - jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaim(OAuth2ParameterNames.SCOPE)); + jwtAccessToken.getTokenValue(), jwtAccessToken.getIssuedAt(), + jwtAccessToken.getExpiresAt(), jwtAccessToken.getClaim(OAuth2ParameterNames.SCOPE)); OAuth2RefreshToken refreshToken = null; if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN)) { @@ -148,7 +149,7 @@ public class OAuth2AuthorizationCodeAuthenticationProvider implements Authentica registeredClient.getTokenSettings().refreshTokenTimeToLive()); } - OidcIdToken idToken = null; + Jwt jwtIdToken = null; if (authorizationRequest.getScopes().contains(OidcScopes.OPENID)) { // @formatter:off context = JwtEncodingContextUtils.idTokenContext(registeredClient, authorization) @@ -161,22 +162,34 @@ public class OAuth2AuthorizationCodeAuthenticationProvider implements Authentica headers = context.getHeaders().build(); claims = context.getClaims().build(); - Jwt jwtIdToken = this.jwtEncoder.encode(headers, claims); - - idToken = new OidcIdToken(jwtIdToken.getTokenValue(), jwtIdToken.getIssuedAt(), - jwtIdToken.getExpiresAt(), jwtIdToken.getClaims()); + jwtIdToken = this.jwtEncoder.encode(headers, claims); } + OidcIdToken idToken; + if (jwtIdToken != null) { + idToken = new OidcIdToken(jwtIdToken.getTokenValue(), jwtIdToken.getIssuedAt(), + jwtIdToken.getExpiresAt(), jwtIdToken.getClaims()); + } else { + idToken = null; + } + + // @formatter:off OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.from(authorization) - .accessToken(accessToken) - .attribute(OAuth2AuthorizationAttributeNames.ACCESS_TOKEN_ATTRIBUTES, jwt); + .token(accessToken, + (metadata) -> + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, jwtAccessToken.getClaims()) + ); if (refreshToken != null) { authorizationBuilder.refreshToken(refreshToken); } if (idToken != null) { - authorizationBuilder.token(idToken); + authorizationBuilder + .token(idToken, + (metadata) -> + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, idToken.getClaims())); } authorization = authorizationBuilder.build(); + // @formatter:on // Invalidate the authorization code as it can only be used once authorization = OAuth2AuthenticationProviderUtils.invalidate(authorization, authorizationCode.getToken()); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java index f0d3a3a..038f1dd 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java @@ -33,7 +33,6 @@ import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.JwtClaimsSet; import org.springframework.security.oauth2.jwt.JwtEncoder; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationAttributeNames; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; @@ -117,17 +116,22 @@ public class OAuth2ClientCredentialsAuthenticationProvider implements Authentica JoseHeader headers = context.getHeaders().build(); JwtClaimsSet claims = context.getClaims().build(); - Jwt jwt = this.jwtEncoder.encode(headers, claims); + Jwt jwtAccessToken = this.jwtEncoder.encode(headers, claims); OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, - jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaim(OAuth2ParameterNames.SCOPE)); + jwtAccessToken.getTokenValue(), jwtAccessToken.getIssuedAt(), + jwtAccessToken.getExpiresAt(), jwtAccessToken.getClaim(OAuth2ParameterNames.SCOPE)); + // @formatter:off OAuth2Authorization authorization = OAuth2Authorization.withRegisteredClient(registeredClient) .principalName(clientPrincipal.getName()) .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) - .token(accessToken) - .attribute(OAuth2AuthorizationAttributeNames.ACCESS_TOKEN_ATTRIBUTES, jwt) + .token(accessToken, + (metadata) -> + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, jwtAccessToken.getClaims())) .build(); + // @formatter:on + this.authorizationService.save(authorization); return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java index cf46cc8..2c36ac7 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java @@ -148,10 +148,11 @@ public class OAuth2RefreshTokenAuthenticationProvider implements AuthenticationP JoseHeader headers = context.getHeaders().build(); JwtClaimsSet claims = context.getClaims().build(); - Jwt jwt = this.jwtEncoder.encode(headers, claims); + Jwt jwtAccessToken = this.jwtEncoder.encode(headers, claims); OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, - jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaim(OAuth2ParameterNames.SCOPE)); + jwtAccessToken.getTokenValue(), jwtAccessToken.getIssuedAt(), + jwtAccessToken.getExpiresAt(), jwtAccessToken.getClaim(OAuth2ParameterNames.SCOPE)); TokenSettings tokenSettings = registeredClient.getTokenSettings(); @@ -160,11 +161,15 @@ public class OAuth2RefreshTokenAuthenticationProvider implements AuthenticationP currentRefreshToken = generateRefreshToken(tokenSettings.refreshTokenTimeToLive()); } + // @formatter:off authorization = OAuth2Authorization.from(authorization) - .accessToken(accessToken) + .token(accessToken, + (metadata) -> + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, jwtAccessToken.getClaims())) .refreshToken(currentRefreshToken) - .attribute(OAuth2AuthorizationAttributeNames.ACCESS_TOKEN_ATTRIBUTES, jwt) .build(); + // @formatter:on + this.authorizationService.save(authorization); return new OAuth2AccessTokenAuthenticationToken(