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 dc3330b..bdccece 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 @@ -32,6 +32,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat import org.springframework.security.oauth2.server.authorization.TokenType; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.config.TokenSettings; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenMetadata; import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens; import org.springframework.util.Assert; @@ -113,16 +114,21 @@ public class OAuth2RefreshTokenAuthenticationProvider implements AuthenticationP scopes = authorizedScopes; } + OAuth2RefreshToken refreshToken = authorization.getTokens().getRefreshToken(); + OAuth2TokenMetadata refreshTokenMetadata = authorization.getTokens().getTokenMetadata(refreshToken); + + if (refreshTokenMetadata.isInvalidated()) { + throw new OAuth2AuthenticationException(new OAuth2Error(OAuth2ErrorCodes.INVALID_GRANT)); + } + Jwt jwt = OAuth2TokenIssuerUtil .issueJwtAccessToken(this.jwtEncoder, authorization.getPrincipalName(), registeredClient.getClientId(), scopes, registeredClient.getTokenSettings().accessTokenTimeToLive()); OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), scopes); TokenSettings tokenSettings = registeredClient.getTokenSettings(); - OAuth2RefreshToken refreshToken; - if (tokenSettings.reuseRefreshTokens()) { - refreshToken = authorization.getTokens().getRefreshToken(); - } else { + + if (!tokenSettings.reuseRefreshTokens()) { refreshToken = OAuth2TokenIssuerUtil.issueRefreshToken(tokenSettings.refreshTokenTimeToLive()); } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java index 628d922..f9cb980 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java @@ -36,6 +36,7 @@ import org.springframework.security.oauth2.server.authorization.TestOAuth2Author import org.springframework.security.oauth2.server.authorization.TokenType; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenMetadata; import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens; import java.time.Instant; @@ -312,4 +313,31 @@ public class OAuth2RefreshTokenAuthenticationProviderTests { .extracting("errorCode") .isEqualTo(OAuth2ErrorCodes.INVALID_GRANT); } + + @Test + public void authenticateWhenRevokedRefreshTokenThenThrowOAuth2AuthenticationException() { + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); + OAuth2RefreshToken refreshToken = new OAuth2RefreshToken2( + "refresh-token", Instant.now().minusSeconds(120), Instant.now().plusSeconds(1000)); + OAuth2TokenMetadata metadata = OAuth2TokenMetadata.builder().invalidated().build(); + OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient) + .tokens(OAuth2Tokens.builder() + .refreshToken(refreshToken, metadata) + .build()) + .build(); + when(this.authorizationService.findByToken( + eq(authorization.getTokens().getRefreshToken().getTokenValue()), + eq(TokenType.REFRESH_TOKEN))) + .thenReturn(authorization); + + OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient); + OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken( + authorization.getTokens().getRefreshToken().getTokenValue(), clientPrincipal); + + assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication)) + .isInstanceOf(OAuth2AuthenticationException.class) + .extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) + .extracting("errorCode") + .isEqualTo(OAuth2ErrorCodes.INVALID_GRANT); + } }