From 7546d18a403b8bce387a96287b692d8bad07f45a Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Fri, 30 Jul 2021 09:48:45 -0400 Subject: [PATCH] Polish gh-379 --- ...thorizationCodeAuthenticationProvider.java | 5 +- ...zationCodeAuthenticationProviderTests.java | 115 +++++++++--------- 2 files changed, 61 insertions(+), 59 deletions(-) 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 b3c587a8..b2b5e44d 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 @@ -192,8 +192,9 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth jwtAccessToken.getExpiresAt(), authorizedScopes); OAuth2RefreshToken refreshToken = null; - if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) - && !registeredClient.getClientAuthenticationMethods().contains(ClientAuthenticationMethod.NONE)) { + if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) && + // Do not issue refresh token to public client + !clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { refreshToken = generateRefreshToken(registeredClient.getTokenSettings().getRefreshTokenTimeToLive()); } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java index 468218f8..81ede143 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java @@ -166,63 +166,6 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests { .isEqualTo(OAuth2ErrorCodes.INVALID_GRANT); } - // gh-296 - @Test - public void authenticateWhenPublicClientThenRefreshTokenIsNotIssued() { - RegisteredClient registeredClient = TestRegisteredClients.registeredPublicClient() - .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) - .build(); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); - when(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE))) - .thenReturn(authorization); - - OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient); - OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( - OAuth2AuthorizationRequest.class.getName()); - OAuth2AuthorizationCodeAuthenticationToken authentication = - new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null); - - when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt()); - - OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = - (OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication); - - ArgumentCaptor jwtEncodingContextCaptor = ArgumentCaptor.forClass(JwtEncodingContext.class); - verify(this.jwtCustomizer).customize(jwtEncodingContextCaptor.capture()); - JwtEncodingContext jwtEncodingContext = jwtEncodingContextCaptor.getValue(); - assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient); - assertThat(jwtEncodingContext.getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName())); - assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization); - assertThat(jwtEncodingContext.getAuthorizedScopes()) - .isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)); - assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN); - assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE); - assertThat(jwtEncodingContext.getAuthorizationGrant()).isEqualTo(authentication); - assertThat(jwtEncodingContext.getHeaders()).isNotNull(); - assertThat(jwtEncodingContext.getClaims()).isNotNull(); - - ArgumentCaptor jwtClaimsSetCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class); - verify(this.jwtEncoder).encode(any(), jwtClaimsSetCaptor.capture()); - JwtClaimsSet jwtClaimsSet = jwtClaimsSetCaptor.getValue(); - - Set scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE); - assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)); - assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName()); - - ArgumentCaptor authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class); - verify(this.authorizationService).save(authorizationCaptor.capture()); - OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue(); - - assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId()); - assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal); - assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken()); - assertThat(accessTokenAuthentication.getAccessToken().getScopes()) - .isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)); - assertThat(accessTokenAuthentication.getRefreshToken()).isNull(); - OAuth2Authorization.Token authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class); - assertThat(authorizationCode.isInvalidated()).isTrue(); - } - @Test public void authenticateWhenCodeIssuedToAnotherClientThenThrowOAuth2AuthenticationException() { OAuth2Authorization authorization = TestOAuth2Authorizations.authorization().build(); @@ -446,6 +389,64 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests { .containsExactly(entry(OidcParameterNames.ID_TOKEN, idToken.getToken().getTokenValue())); } + // gh-296 + @Test + public void authenticateWhenPublicClientThenRefreshTokenNotIssued() { + RegisteredClient registeredClient = TestRegisteredClients.registeredPublicClient() + .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) + .build(); + OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + when(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE))) + .thenReturn(authorization); + + OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( + registeredClient, ClientAuthenticationMethod.NONE, null); + OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( + OAuth2AuthorizationRequest.class.getName()); + OAuth2AuthorizationCodeAuthenticationToken authentication = + new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null); + + when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt()); + + OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = + (OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication); + + ArgumentCaptor jwtEncodingContextCaptor = ArgumentCaptor.forClass(JwtEncodingContext.class); + verify(this.jwtCustomizer).customize(jwtEncodingContextCaptor.capture()); + JwtEncodingContext jwtEncodingContext = jwtEncodingContextCaptor.getValue(); + assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient); + assertThat(jwtEncodingContext.getPrincipal()).isEqualTo(authorization.getAttribute(Principal.class.getName())); + assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization); + assertThat(jwtEncodingContext.getAuthorizedScopes()) + .isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)); + assertThat(jwtEncodingContext.getTokenType()).isEqualTo(OAuth2TokenType.ACCESS_TOKEN); + assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE); + assertThat(jwtEncodingContext.getAuthorizationGrant()).isEqualTo(authentication); + assertThat(jwtEncodingContext.getHeaders()).isNotNull(); + assertThat(jwtEncodingContext.getClaims()).isNotNull(); + + ArgumentCaptor jwtClaimsSetCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class); + verify(this.jwtEncoder).encode(any(), jwtClaimsSetCaptor.capture()); + JwtClaimsSet jwtClaimsSet = jwtClaimsSetCaptor.getValue(); + + Set scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE); + assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)); + assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName()); + + ArgumentCaptor authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class); + verify(this.authorizationService).save(authorizationCaptor.capture()); + OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue(); + + assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId()); + assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal); + assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken().getToken()); + assertThat(accessTokenAuthentication.getAccessToken().getScopes()) + .isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME)); + assertThat(accessTokenAuthentication.getRefreshToken()).isNull(); + OAuth2Authorization.Token authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class); + assertThat(authorizationCode.isInvalidated()).isTrue(); + } + @Test public void authenticateWhenTokenTimeToLiveConfiguredThenTokenExpirySet() { Duration accessTokenTTL = Duration.ofHours(2);