Fix NPE on access token in OAuth2AuthorizationCodeAuthenticationProvider

Closes gh-1233
This commit is contained in:
Pavel Efros
2023-05-25 15:09:56 +02:00
committed by Joe Grandja
parent 9c1ec348af
commit 6e1ed9fd87
2 changed files with 32 additions and 4 deletions

View File

@@ -36,6 +36,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.oauth2.core.AbstractOAuth2Token;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClaimAccessor;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
@@ -154,12 +155,12 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth
if (!authorizationCode.isActive()) {
if (authorizationCode.isInvalidated()) {
OAuth2Token token = authorization.getRefreshToken() != null ?
authorization.getRefreshToken().getToken() :
authorization.getAccessToken().getToken();
OAuth2Authorization.Token<? extends AbstractOAuth2Token> token = authorization.getRefreshToken() != null ?
authorization.getRefreshToken() :
authorization.getAccessToken();
if (token != null) {
// Invalidate the access (and refresh) token as the client is attempting to use the authorization code more than once
authorization = OAuth2AuthenticationProviderUtils.invalidate(authorization, token);
authorization = OAuth2AuthenticationProviderUtils.invalidate(authorization, token.getToken());
this.authorizationService.save(authorization);
if (this.logger.isWarnEnabled()) {
this.logger.warn(LogMessage.format("Invalidated authorization token(s) previously issued to registered client '%s'", registeredClient.getId()));

View File

@@ -283,6 +283,33 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
assertThat(updatedAuthorization.getRefreshToken().isInvalidated()).isTrue();
}
// gh PR 1233
@Test
public void authenticateWhenInvalidatedCodeAndNullRefreshAndAccessTokensThenThrowOAuth2AuthenticationException() {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
OAuth2AuthorizationCode authorizationCode = new OAuth2AuthorizationCode(
AUTHORIZATION_CODE, Instant.now(), Instant.now().plusSeconds(120));
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient, authorizationCode)
.token(authorizationCode, (metadata) -> metadata.put(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME, true))
.build();
when(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
.thenReturn(authorization);
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute(
OAuth2AuthorizationRequest.class.getName());
OAuth2AuthorizationCodeAuthenticationToken authentication =
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
.isInstanceOf(OAuth2AuthenticationException.class)
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
.extracting("errorCode")
.isEqualTo(OAuth2ErrorCodes.INVALID_GRANT);
}
// gh-290
@Test
public void authenticateWhenExpiredCodeThenThrowOAuth2AuthenticationException() {