Skip to content

Commit

Permalink
Do not issue refresh token to public client
Browse files Browse the repository at this point in the history
  • Loading branch information
sjohnr committed Jul 28, 2021
1 parent 7f294ab commit b077e5c
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ public Authentication authenticate(Authentication authentication) throws Authent
jwtAccessToken.getExpiresAt(), authorizedScopes);

OAuth2RefreshToken refreshToken = null;
if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN)) {
if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN)
&& StringUtils.hasText(registeredClient.getClientSecret())) {
refreshToken = generateRefreshToken(registeredClient.getTokenSettings().getRefreshTokenTimeToLive());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,63 @@ public void authenticateWhenInvalidCodeThenThrowOAuth2AuthenticationException()
.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<JwtEncodingContext> jwtEncodingContextCaptor = ArgumentCaptor.forClass(JwtEncodingContext.class);
verify(this.jwtCustomizer).customize(jwtEncodingContextCaptor.capture());
JwtEncodingContext jwtEncodingContext = jwtEncodingContextCaptor.getValue();
assertThat(jwtEncodingContext.getRegisteredClient()).isEqualTo(registeredClient);
assertThat(jwtEncodingContext.<Authentication>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.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.getHeaders()).isNotNull();
assertThat(jwtEncodingContext.getClaims()).isNotNull();

ArgumentCaptor<JwtClaimsSet> jwtClaimsSetCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class);
verify(this.jwtEncoder).encode(any(), jwtClaimsSetCaptor.capture());
JwtClaimsSet jwtClaimsSet = jwtClaimsSetCaptor.getValue();

Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
assertThat(jwtClaimsSet.getSubject()).isEqualTo(authorization.getPrincipalName());

ArgumentCaptor<OAuth2Authorization> 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<OAuth2AuthorizationCode> authorizationCode = updatedAuthorization.getToken(OAuth2AuthorizationCode.class);
assertThat(authorizationCode.isInvalidated()).isTrue();
}

@Test
public void authenticateWhenCodeIssuedToAnotherClientThenThrowOAuth2AuthenticationException() {
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization().build();
Expand Down

0 comments on commit b077e5c

Please sign in to comment.