|
@@ -13,29 +13,22 @@
|
|
|
* See the License for the specific language governing permissions and
|
|
|
* limitations under the License.
|
|
|
*/
|
|
|
-
|
|
|
package org.springframework.security.oauth2.server.authorization.authentication;
|
|
|
|
|
|
-import java.time.Instant;
|
|
|
-import java.util.HashSet;
|
|
|
-import java.util.Set;
|
|
|
-import java.util.UUID;
|
|
|
-
|
|
|
-import org.assertj.core.api.Assertions;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
import org.mockito.ArgumentCaptor;
|
|
|
-
|
|
|
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
|
|
+import org.springframework.security.authentication.TestingAuthenticationToken;
|
|
|
+import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
|
|
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
|
|
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
|
|
|
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
|
|
import org.springframework.security.oauth2.jose.JoseHeaderNames;
|
|
|
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
|
|
import org.springframework.security.oauth2.jwt.Jwt;
|
|
|
-import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
|
|
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
|
|
+import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationAttributeNames;
|
|
|
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
|
|
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
|
|
import org.springframework.security.oauth2.server.authorization.TokenType;
|
|
@@ -43,59 +36,46 @@ import org.springframework.security.oauth2.server.authorization.client.Registere
|
|
|
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
|
|
import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens;
|
|
|
|
|
|
+import java.time.Instant;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
|
|
|
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
|
+import static org.mockito.ArgumentMatchers.eq;
|
|
|
import static org.mockito.Mockito.mock;
|
|
|
import static org.mockito.Mockito.verify;
|
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
|
/**
|
|
|
+ * Tests for {@link OAuth2RefreshTokenAuthenticationProvider}.
|
|
|
+ *
|
|
|
* @author Alexey Nesterov
|
|
|
* @since 0.0.3
|
|
|
*/
|
|
|
public class OAuth2RefreshTokenAuthenticationProviderTests {
|
|
|
-
|
|
|
- private final String NEW_ACCESS_TOKEN_VALUE = UUID.randomUUID().toString();
|
|
|
- private final String REFRESH_TOKEN_VALUE = UUID.randomUUID().toString();
|
|
|
-
|
|
|
- private final RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
|
|
|
- private final OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(this.registeredClient);
|
|
|
-
|
|
|
- private final OAuth2AccessToken existingAccessToken = new OAuth2AccessToken(
|
|
|
- OAuth2AccessToken.TokenType.BEARER,
|
|
|
- "old-test-access-token",
|
|
|
- Instant.now(),
|
|
|
- Instant.now().plusSeconds(10),
|
|
|
- this.registeredClient.getScopes());
|
|
|
-
|
|
|
- private final OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(this.registeredClient)
|
|
|
- .tokens(OAuth2Tokens.builder()
|
|
|
- .accessToken(this.existingAccessToken)
|
|
|
- .refreshToken(new OAuth2RefreshToken(REFRESH_TOKEN_VALUE, Instant.now(), Instant.now().plusSeconds(60)))
|
|
|
- .build())
|
|
|
- .build();
|
|
|
-
|
|
|
private OAuth2AuthorizationService authorizationService;
|
|
|
private JwtEncoder jwtEncoder;
|
|
|
- private OAuth2RefreshTokenAuthenticationProvider provider;
|
|
|
+ private OAuth2RefreshTokenAuthenticationProvider authenticationProvider;
|
|
|
|
|
|
@Before
|
|
|
public void setUp() {
|
|
|
this.authorizationService = mock(OAuth2AuthorizationService.class);
|
|
|
this.jwtEncoder = mock(JwtEncoder.class);
|
|
|
- this.provider = new OAuth2RefreshTokenAuthenticationProvider(this.authorizationService, this.jwtEncoder);
|
|
|
-
|
|
|
- Jwt jwt = Jwt.withTokenValue(NEW_ACCESS_TOKEN_VALUE)
|
|
|
- .issuedAt(Instant.now())
|
|
|
- .header(JoseHeaderNames.ALG, SignatureAlgorithm.RS256.getName())
|
|
|
- .build();
|
|
|
-
|
|
|
+ Jwt jwt = Jwt.withTokenValue("refreshed-access-token")
|
|
|
+ .header(JoseHeaderNames.ALG, SignatureAlgorithm.RS256.getName())
|
|
|
+ .issuedAt(Instant.now())
|
|
|
+ .expiresAt(Instant.now().plus(1, ChronoUnit.HOURS))
|
|
|
+ .build();
|
|
|
when(this.jwtEncoder.encode(any(), any())).thenReturn(jwt);
|
|
|
+ this.authenticationProvider = new OAuth2RefreshTokenAuthenticationProvider(
|
|
|
+ this.authorizationService, this.jwtEncoder);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void constructorWhenAuthorizationServiceNullThenThrowException() {
|
|
|
+ public void constructorWhenAuthorizationServiceNullThenThrowIllegalArgumentException() {
|
|
|
assertThatThrownBy(() -> new OAuth2RefreshTokenAuthenticationProvider(null, this.jwtEncoder))
|
|
|
.isInstanceOf(IllegalArgumentException.class)
|
|
|
.extracting(Throwable::getMessage)
|
|
@@ -103,7 +83,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void constructorWhenJwtEncoderNullThenThrowException() {
|
|
|
+ public void constructorWhenJwtEncoderNullThenThrowIllegalArgumentException() {
|
|
|
assertThatThrownBy(() -> new OAuth2RefreshTokenAuthenticationProvider(this.authorizationService, null))
|
|
|
.isInstanceOf(IllegalArgumentException.class)
|
|
|
.extracting(Throwable::getMessage)
|
|
@@ -112,152 +92,173 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
|
|
|
|
|
|
@Test
|
|
|
public void supportsWhenSupportedAuthenticationThenTrue() {
|
|
|
- assertThat(this.provider.supports(OAuth2RefreshTokenAuthenticationToken.class)).isTrue();
|
|
|
+ assertThat(this.authenticationProvider.supports(OAuth2RefreshTokenAuthenticationToken.class)).isTrue();
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void supportsWhenUnsupportedAuthenticationThenFalse() {
|
|
|
- assertThat(this.provider.supports(OAuth2ClientCredentialsAuthenticationToken.class)).isFalse();
|
|
|
+ assertThat(this.authenticationProvider.supports(OAuth2ClientCredentialsAuthenticationToken.class)).isFalse();
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void authenticateWhenRefreshTokenExistsThenReturnAuthentication() {
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(this.authorization);
|
|
|
+ public void authenticateWhenValidRefreshTokenThenReturnAccessToken() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).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);
|
|
|
|
|
|
- OAuth2RefreshTokenAuthenticationToken token = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, this.clientPrincipal);
|
|
|
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
|
|
- (OAuth2AccessTokenAuthenticationToken) this.provider.authenticate(token);
|
|
|
-
|
|
|
- ArgumentCaptor<JwtClaimsSet> claimsSetArgumentCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class);
|
|
|
- verify(this.jwtEncoder).encode(any(), claimsSetArgumentCaptor.capture());
|
|
|
-
|
|
|
- assertThat(claimsSetArgumentCaptor.getValue().getSubject()).isEqualTo(this.authorization.getPrincipalName());
|
|
|
-
|
|
|
- assertThat(accessTokenAuthentication.getAccessToken()).isNotNull();
|
|
|
- assertThat(accessTokenAuthentication.getAccessToken().getTokenValue()).isEqualTo(NEW_ACCESS_TOKEN_VALUE);
|
|
|
- assertThat(accessTokenAuthentication.getAccessToken().getScopes()).containsAll(this.existingAccessToken.getScopes());
|
|
|
- assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(this.clientPrincipal);
|
|
|
- assertThat(accessTokenAuthentication.getRegisteredClient()).isEqualTo(this.registeredClient);
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- public void authenticateWhenRefreshTokenExistsThenUpdatesAuthorization() {
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(this.authorization);
|
|
|
-
|
|
|
- OAuth2RefreshTokenAuthenticationToken token = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, this.clientPrincipal);
|
|
|
- this.provider.authenticate(token);
|
|
|
+ (OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
|
|
|
|
|
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
|
|
|
verify(this.authorizationService).save(authorizationCaptor.capture());
|
|
|
OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
|
|
|
|
|
|
- assertThat(updatedAuthorization.getTokens().getAccessToken()).isNotNull();
|
|
|
- assertThat(updatedAuthorization.getTokens().getAccessToken().getTokenValue()).isEqualTo(NEW_ACCESS_TOKEN_VALUE);
|
|
|
+ assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
|
|
|
+ assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
|
|
|
+ assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getTokens().getAccessToken());
|
|
|
+ assertThat(updatedAuthorization.getTokens().getAccessToken()).isNotEqualTo(authorization.getTokens().getAccessToken());
|
|
|
+ assertThat(accessTokenAuthentication.getRefreshToken()).isEqualTo(updatedAuthorization.getTokens().getRefreshToken());
|
|
|
+ // By default, refresh token is reused
|
|
|
+ assertThat(updatedAuthorization.getTokens().getRefreshToken()).isEqualTo(authorization.getTokens().getRefreshToken());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void authenticateWhenClientSetToReuseRefreshTokensThenKeepsRefreshTokenValue() {
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(this.authorization);
|
|
|
-
|
|
|
- RegisteredClient clientWithReuseTokensTrue = TestRegisteredClients.registeredClient2()
|
|
|
- .tokenSettings(tokenSettings -> tokenSettings.reuseRefreshTokens(true))
|
|
|
+ public void authenticateWhenReuseRefreshTokensFalseThenReturnNewRefreshToken() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
|
|
+ .tokenSettings(tokenSettings -> tokenSettings.reuseRefreshTokens(false))
|
|
|
.build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
|
|
+ when(this.authorizationService.findByToken(
|
|
|
+ eq(authorization.getTokens().getRefreshToken().getTokenValue()),
|
|
|
+ eq(TokenType.REFRESH_TOKEN)))
|
|
|
+ .thenReturn(authorization);
|
|
|
|
|
|
- OAuth2RefreshTokenAuthenticationToken token = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, new OAuth2ClientAuthenticationToken(clientWithReuseTokensTrue));
|
|
|
- OAuth2AccessTokenAuthenticationToken authentication = (OAuth2AccessTokenAuthenticationToken) this.provider.authenticate(token);
|
|
|
-
|
|
|
- ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
|
|
|
- verify(this.authorizationService).save(authorizationCaptor.capture());
|
|
|
- OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
|
|
|
-
|
|
|
- assertThat(updatedAuthorization.getTokens().getRefreshToken()).isNotNull();
|
|
|
- assertThat(updatedAuthorization.getTokens().getRefreshToken()).isEqualTo(this.authorization.getTokens().getRefreshToken());
|
|
|
- assertThat(authentication.getRefreshToken()).isEqualTo(this.authorization.getTokens().getRefreshToken());
|
|
|
- }
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient);
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ authorization.getTokens().getRefreshToken().getTokenValue(), clientPrincipal);
|
|
|
|
|
|
- @Test
|
|
|
- public void authenticateWhenClientSetToGenerateNewRefreshTokensThenGenerateNewToken() {
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(this.authorization);
|
|
|
-
|
|
|
- RegisteredClient clientWithReuseTokensFalse = TestRegisteredClients.registeredClient2()
|
|
|
- .tokenSettings(tokenSettings -> tokenSettings.reuseRefreshTokens(false))
|
|
|
- .build();
|
|
|
-
|
|
|
- OAuth2RefreshTokenAuthenticationToken token =
|
|
|
- new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, new OAuth2ClientAuthenticationToken(clientWithReuseTokensFalse));
|
|
|
-
|
|
|
- OAuth2AccessTokenAuthenticationToken authentication = (OAuth2AccessTokenAuthenticationToken) this.provider.authenticate(token);
|
|
|
+ OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
|
|
+ (OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
|
|
|
|
|
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
|
|
|
verify(this.authorizationService).save(authorizationCaptor.capture());
|
|
|
OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
|
|
|
|
|
|
- assertThat(updatedAuthorization.getTokens().getRefreshToken()).isNotNull();
|
|
|
- assertThat(updatedAuthorization.getTokens().getRefreshToken()).isNotEqualTo(this.authorization.getTokens().getRefreshToken());
|
|
|
- assertThat(authentication.getRefreshToken()).isNotEqualTo(this.authorization.getTokens().getRefreshToken());
|
|
|
+ assertThat(accessTokenAuthentication.getRefreshToken()).isEqualTo(updatedAuthorization.getTokens().getRefreshToken());
|
|
|
+ assertThat(updatedAuthorization.getTokens().getRefreshToken()).isNotEqualTo(authorization.getTokens().getRefreshToken());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void authenticateWhenRefreshTokenHasScopesThenIncludeScopes() {
|
|
|
- Set<String> requestedScopes = new HashSet<>();
|
|
|
- requestedScopes.add("email");
|
|
|
- requestedScopes.add("openid");
|
|
|
-
|
|
|
- OAuth2RefreshTokenAuthenticationToken tokenWithScopes
|
|
|
- = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, this.clientPrincipal, requestedScopes);
|
|
|
-
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(this.authorization);
|
|
|
+ public void authenticateWhenRequestedScopesAuthorizedThenAccessTokenIncludesScopes() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
|
|
+ when(this.authorizationService.findByToken(
|
|
|
+ eq(authorization.getTokens().getRefreshToken().getTokenValue()),
|
|
|
+ eq(TokenType.REFRESH_TOKEN)))
|
|
|
+ .thenReturn(authorization);
|
|
|
+
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient);
|
|
|
+ Set<String> authorizedScopes = authorization.getAttribute(OAuth2AuthorizationAttributeNames.AUTHORIZED_SCOPES);
|
|
|
+ Set<String> requestedScopes = new HashSet<>(authorizedScopes);
|
|
|
+ requestedScopes.remove("email");
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ authorization.getTokens().getRefreshToken().getTokenValue(), clientPrincipal, requestedScopes);
|
|
|
|
|
|
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
|
|
- (OAuth2AccessTokenAuthenticationToken) this.provider.authenticate(tokenWithScopes);
|
|
|
+ (OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
|
|
|
|
|
- assertThat(accessTokenAuthentication.getAccessToken()).isNotNull();
|
|
|
- assertThat(accessTokenAuthentication.getAccessToken().getScopes()).containsAll(requestedScopes);
|
|
|
+ assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(requestedScopes);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void authenticateWhenRefreshTokenHasNotApprovedScopesThenThrowException() {
|
|
|
- Set<String> requestedScopes = new HashSet<>();
|
|
|
- requestedScopes.add("email");
|
|
|
- requestedScopes.add("another-scope");
|
|
|
-
|
|
|
- OAuth2RefreshTokenAuthenticationToken tokenWithScopes
|
|
|
- = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, this.clientPrincipal, requestedScopes);
|
|
|
-
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(this.authorization);
|
|
|
-
|
|
|
- assertThatThrownBy(() -> this.provider.authenticate(tokenWithScopes))
|
|
|
+ public void authenticateWhenRequestedScopesNotAuthorizedThenThrowOAuth2AuthenticationException() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
|
|
+ when(this.authorizationService.findByToken(
|
|
|
+ eq(authorization.getTokens().getRefreshToken().getTokenValue()),
|
|
|
+ eq(TokenType.REFRESH_TOKEN)))
|
|
|
+ .thenReturn(authorization);
|
|
|
+
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient);
|
|
|
+ Set<String> authorizedScopes = authorization.getAttribute(OAuth2AuthorizationAttributeNames.AUTHORIZED_SCOPES);
|
|
|
+ Set<String> requestedScopes = new HashSet<>(authorizedScopes);
|
|
|
+ requestedScopes.add("unauthorized");
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ authorization.getTokens().getRefreshToken().getTokenValue(), clientPrincipal, requestedScopes);
|
|
|
+
|
|
|
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
|
|
|
.isInstanceOf(OAuth2AuthenticationException.class)
|
|
|
- .extracting((Throwable e) -> ((OAuth2AuthenticationException) e).getError())
|
|
|
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
.extracting("errorCode")
|
|
|
.isEqualTo(OAuth2ErrorCodes.INVALID_SCOPE);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void authenticateWhenRefreshTokenDoesNotExistThenThrowException() {
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(null);
|
|
|
+ public void authenticateWhenInvalidRefreshTokenThenThrowOAuth2AuthenticationException() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient);
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ "invalid", clientPrincipal);
|
|
|
|
|
|
- OAuth2RefreshTokenAuthenticationToken token = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, this.clientPrincipal);
|
|
|
- assertThatThrownBy(() -> this.provider.authenticate(token))
|
|
|
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
|
|
|
.isInstanceOf(OAuth2AuthenticationException.class)
|
|
|
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
.extracting("errorCode")
|
|
|
.isEqualTo(OAuth2ErrorCodes.INVALID_GRANT);
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void authenticateWhenClientPrincipalNotOAuth2ClientAuthenticationTokenThenThrowOAuth2AuthenticationException() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ TestingAuthenticationToken clientPrincipal = new TestingAuthenticationToken(
|
|
|
+ registeredClient.getClientId(), registeredClient.getClientSecret());
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ "refresh-token", clientPrincipal);
|
|
|
+
|
|
|
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
|
|
|
+ .isInstanceOf(OAuth2AuthenticationException.class)
|
|
|
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
+ .extracting("errorCode")
|
|
|
+ .isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT);
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void authenticateWhenClientPrincipalNotAuthenticatedThenThrowOAuth2AuthenticationException() {
|
|
|
- OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(this.registeredClient.getClientId(), null);
|
|
|
- OAuth2RefreshTokenAuthenticationToken token = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, clientPrincipal);
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
|
|
|
+ registeredClient.getClientId(), registeredClient.getClientSecret(), null);
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ "refresh-token", clientPrincipal);
|
|
|
+
|
|
|
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
|
|
|
+ .isInstanceOf(OAuth2AuthenticationException.class)
|
|
|
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
+ .extracting("errorCode")
|
|
|
+ .isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT);
|
|
|
+ }
|
|
|
|
|
|
- Assertions.assertThatThrownBy(() -> this.provider.authenticate(token))
|
|
|
+ @Test
|
|
|
+ public void authenticateWhenRefreshTokenIssuedToAnotherClientThenThrowOAuth2AuthenticationException() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
|
|
+ when(this.authorizationService.findByToken(
|
|
|
+ eq(authorization.getTokens().getRefreshToken().getTokenValue()),
|
|
|
+ eq(TokenType.REFRESH_TOKEN)))
|
|
|
+ .thenReturn(authorization);
|
|
|
+
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
|
|
|
+ TestRegisteredClients.registeredClient2().build());
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ authorization.getTokens().getRefreshToken().getTokenValue(), clientPrincipal);
|
|
|
+
|
|
|
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
|
|
|
.isInstanceOf(OAuth2AuthenticationException.class)
|
|
|
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
.extracting("errorCode")
|
|
@@ -265,23 +266,47 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void authenticateWhenRefreshTokenHasExpiredThenThrowException() {
|
|
|
- OAuth2RefreshToken expiredRefreshToken = new OAuth2RefreshToken(REFRESH_TOKEN_VALUE, Instant.now().minusSeconds(120), Instant.now().minusSeconds(60));
|
|
|
- OAuth2Authorization authorizationWithExpiredRefreshToken =
|
|
|
- OAuth2Authorization
|
|
|
- .from(this.authorization)
|
|
|
- .tokens(OAuth2Tokens.from(this.authorization.getTokens()).refreshToken(expiredRefreshToken).build())
|
|
|
- .build();
|
|
|
+ public void authenticateWhenClientNotAuthorizedToRefreshTokenThenThrowOAuth2AuthenticationException() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
|
|
+ .authorizationGrantTypes(grantTypes -> grantTypes.remove(AuthorizationGrantType.REFRESH_TOKEN))
|
|
|
+ .build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
|
|
+ when(this.authorizationService.findByToken(
|
|
|
+ eq(authorization.getTokens().getRefreshToken().getTokenValue()),
|
|
|
+ eq(TokenType.REFRESH_TOKEN)))
|
|
|
+ .thenReturn(authorization);
|
|
|
|
|
|
- OAuth2RefreshTokenAuthenticationToken token
|
|
|
- = new OAuth2RefreshTokenAuthenticationToken(REFRESH_TOKEN_VALUE, this.clientPrincipal);
|
|
|
+ OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient);
|
|
|
+ OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
|
|
|
+ authorization.getTokens().getRefreshToken().getTokenValue(), clientPrincipal);
|
|
|
|
|
|
- when(this.authorizationService.findByToken(REFRESH_TOKEN_VALUE, TokenType.REFRESH_TOKEN))
|
|
|
- .thenReturn(authorizationWithExpiredRefreshToken);
|
|
|
+ assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
|
|
|
+ .isInstanceOf(OAuth2AuthenticationException.class)
|
|
|
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
+ .extracting("errorCode")
|
|
|
+ .isEqualTo(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT);
|
|
|
+ }
|
|
|
|
|
|
- assertThatThrownBy(() -> this.provider.authenticate(token))
|
|
|
+ @Test
|
|
|
+ public void authenticateWhenExpiredRefreshTokenThenThrowOAuth2AuthenticationException() {
|
|
|
+ RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
|
|
+ OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
|
|
+ OAuth2RefreshToken expiredRefreshToken = new OAuth2RefreshToken(
|
|
|
+ "expired-refresh-token", Instant.now().minusSeconds(120), Instant.now().minusSeconds(60));
|
|
|
+ OAuth2Tokens tokens = OAuth2Tokens.from(authorization.getTokens()).refreshToken(expiredRefreshToken).build();
|
|
|
+ authorization = OAuth2Authorization.from(authorization).tokens(tokens).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((Throwable e) -> ((OAuth2AuthenticationException) e).getError())
|
|
|
+ .extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
|
|
|
.extracting("errorCode")
|
|
|
.isEqualTo(OAuth2ErrorCodes.INVALID_GRANT);
|
|
|
}
|