Ensure refresh token is not revoked

Closes gh-158
This commit is contained in:
Laurentiu Spilca 2020-11-28 14:14:22 +02:00 committed by Joe Grandja
parent 7f8aff7982
commit 7fae37f0b5
2 changed files with 38 additions and 4 deletions

View File

@ -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());
}

View File

@ -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);
}
}