From e8120e203b2a26da2976396f7f9083d5ab43d644 Mon Sep 17 00:00:00 2001 From: "felipe.malaquias" Date: Thu, 24 Jul 2025 19:06:46 +0200 Subject: [PATCH] provide access token to refresh token generator Signed-off-by: felipe.malaquias --- .../OAuth2RefreshTokenAuthenticationProvider.java | 11 +++++++---- ...OAuth2RefreshTokenAuthenticationProviderTests.java | 9 +++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) 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 a9e3fbab7..ec8c617ff 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 @@ -165,7 +165,7 @@ public Authentication authenticate(Authentication authentication) throws Authent Jwt dPoPProof = DPoPProofVerifier.verifyIfAvailable(refreshTokenAuthentication); if (dPoPProof != null - & clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { + && clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { // For public clients, verify the DPoP Proof public key is same as (current) // access token public key binding Map accessTokenClaims = authorization.getAccessToken().getClaims(); @@ -215,7 +215,10 @@ public Authentication authenticate(Authentication authentication) throws Authent // ----- Refresh token ----- OAuth2RefreshToken currentRefreshToken = refreshToken.getToken(); if (!registeredClient.getTokenSettings().isReuseRefreshTokens()) { - tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build(); + tokenContext = tokenContextBuilder + .tokenType(OAuth2TokenType.REFRESH_TOKEN) + .authorization(authorizationBuilder.build()) // allows refresh token to retrieve access token + .build(); OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext); if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) { OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, @@ -253,8 +256,8 @@ public Authentication authenticate(Authentication authentication) throws Authent idToken = new OidcIdToken(generatedIdToken.getTokenValue(), generatedIdToken.getIssuedAt(), generatedIdToken.getExpiresAt(), ((Jwt) generatedIdToken).getClaims()); - authorizationBuilder.token(idToken, - (metadata) -> metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, idToken.getClaims())); + authorizationBuilder.token(idToken, metadata -> + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, idToken.getClaims())); } else { idToken = null; 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 32eb57ed7..e3d1d0628 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 @@ -22,6 +22,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -328,6 +329,14 @@ public void authenticateWhenReuseRefreshTokensFalseThenReturnNewRefreshToken() { OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) this.authenticationProvider .authenticate(authentication); + ArgumentCaptor oAuth2TokenContextCaptor = ArgumentCaptor.forClass(OAuth2TokenContext.class); + verify(this.tokenGenerator, times(2)).generate(oAuth2TokenContextCaptor.capture()); + // tokenGenerator is first invoked for generating a new access token and then for generating the refresh token for this access token + List tokenContexts = oAuth2TokenContextCaptor.getAllValues(); + assertThat(tokenContexts).hasSize(2); + assertThat(tokenContexts.get(0).getAuthorization().getAccessToken().getToken().getTokenValue()).isEqualTo("access-token"); + assertThat(tokenContexts.get(1).getAuthorization().getAccessToken().getToken().getTokenValue()).isEqualTo("refreshed-access-token"); + ArgumentCaptor authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class); verify(this.authorizationService).save(authorizationCaptor.capture()); OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();