Introduce OAuth2Tokens
Closes gh-137
This commit is contained in:
@@ -20,6 +20,7 @@ import org.junit.Test;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -129,7 +130,7 @@ public class InMemoryOAuth2AuthorizationServiceTests {
|
||||
OAuth2Authorization authorization = OAuth2Authorization.withRegisteredClient(REGISTERED_CLIENT)
|
||||
.principalName(PRINCIPAL_NAME)
|
||||
.attribute(OAuth2AuthorizationAttributeNames.CODE, AUTHORIZATION_CODE)
|
||||
.accessToken(accessToken)
|
||||
.tokens(OAuth2Tokens.builder().accessToken(accessToken).build())
|
||||
.build();
|
||||
this.authorizationService.save(authorization);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.junit.Test;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -57,14 +58,14 @@ public class OAuth2AuthorizationTests {
|
||||
public void fromWhenAuthorizationProvidedThenCopied() {
|
||||
OAuth2Authorization authorization = OAuth2Authorization.withRegisteredClient(REGISTERED_CLIENT)
|
||||
.principalName(PRINCIPAL_NAME)
|
||||
.accessToken(ACCESS_TOKEN)
|
||||
.tokens(OAuth2Tokens.builder().accessToken(ACCESS_TOKEN).build())
|
||||
.attribute(OAuth2AuthorizationAttributeNames.CODE, AUTHORIZATION_CODE)
|
||||
.build();
|
||||
OAuth2Authorization authorizationResult = OAuth2Authorization.from(authorization).build();
|
||||
|
||||
assertThat(authorizationResult.getRegisteredClientId()).isEqualTo(authorization.getRegisteredClientId());
|
||||
assertThat(authorizationResult.getPrincipalName()).isEqualTo(authorization.getPrincipalName());
|
||||
assertThat(authorizationResult.getAccessToken()).isEqualTo(authorization.getAccessToken());
|
||||
assertThat(authorizationResult.getTokens().getAccessToken()).isEqualTo(authorization.getTokens().getAccessToken());
|
||||
assertThat(authorizationResult.getAttributes()).isEqualTo(authorization.getAttributes());
|
||||
}
|
||||
|
||||
@@ -97,13 +98,13 @@ public class OAuth2AuthorizationTests {
|
||||
public void buildWhenAllAttributesAreProvidedThenAllAttributesAreSet() {
|
||||
OAuth2Authorization authorization = OAuth2Authorization.withRegisteredClient(REGISTERED_CLIENT)
|
||||
.principalName(PRINCIPAL_NAME)
|
||||
.accessToken(ACCESS_TOKEN)
|
||||
.tokens(OAuth2Tokens.builder().accessToken(ACCESS_TOKEN).build())
|
||||
.attribute(OAuth2AuthorizationAttributeNames.CODE, AUTHORIZATION_CODE)
|
||||
.build();
|
||||
|
||||
assertThat(authorization.getRegisteredClientId()).isEqualTo(REGISTERED_CLIENT.getId());
|
||||
assertThat(authorization.getPrincipalName()).isEqualTo(PRINCIPAL_NAME);
|
||||
assertThat(authorization.getAccessToken()).isEqualTo(ACCESS_TOKEN);
|
||||
assertThat(authorization.getTokens().getAccessToken()).isEqualTo(ACCESS_TOKEN);
|
||||
assertThat(authorization.getAttributes()).containsExactly(
|
||||
entry(OAuth2AuthorizationAttributeNames.CODE, AUTHORIZATION_CODE));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
@@ -52,7 +53,7 @@ public class TestOAuth2Authorizations {
|
||||
.build();
|
||||
return OAuth2Authorization.withRegisteredClient(registeredClient)
|
||||
.principalName("principal")
|
||||
.accessToken(accessToken)
|
||||
.tokens(OAuth2Tokens.builder().accessToken(accessToken).build())
|
||||
.attribute(OAuth2AuthorizationAttributeNames.CODE, "code")
|
||||
.attribute(OAuth2AuthorizationAttributeNames.AUTHORIZATION_REQUEST, authorizationRequest)
|
||||
.attribute(OAuth2AuthorizationAttributeNames.AUTHORIZED_SCOPES, authorizationRequest.getScopes());
|
||||
|
||||
@@ -203,8 +203,8 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
|
||||
assertThat(accessTokenAuthentication.getRegisteredClient().getId()).isEqualTo(updatedAuthorization.getRegisteredClientId());
|
||||
assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
|
||||
assertThat(updatedAuthorization.getAccessToken()).isNotNull();
|
||||
assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getAccessToken());
|
||||
assertThat(updatedAuthorization.getTokens().getAccessToken()).isNotNull();
|
||||
assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(updatedAuthorization.getTokens().getAccessToken());
|
||||
}
|
||||
|
||||
private static Jwt createJwt() {
|
||||
|
||||
@@ -156,10 +156,10 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
|
||||
|
||||
assertThat(authorization.getRegisteredClientId()).isEqualTo(clientPrincipal.getRegisteredClient().getId());
|
||||
assertThat(authorization.getPrincipalName()).isEqualTo(clientPrincipal.getName());
|
||||
assertThat(authorization.getAccessToken()).isNotNull();
|
||||
assertThat(authorization.getAccessToken().getScopes()).isEqualTo(clientPrincipal.getRegisteredClient().getScopes());
|
||||
assertThat(authorization.getTokens().getAccessToken()).isNotNull();
|
||||
assertThat(authorization.getTokens().getAccessToken().getScopes()).isEqualTo(clientPrincipal.getRegisteredClient().getScopes());
|
||||
assertThat(accessTokenAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
|
||||
assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(authorization.getAccessToken());
|
||||
assertThat(accessTokenAuthentication.getAccessToken()).isEqualTo(authorization.getTokens().getAccessToken());
|
||||
}
|
||||
|
||||
private static Jwt createJwt() {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.token;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link OAuth2TokenMetadata}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class OAuth2TokenMetadataTests {
|
||||
|
||||
@Test
|
||||
public void metadataWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() ->
|
||||
OAuth2TokenMetadata.builder()
|
||||
.metadata(null, "value"))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataWhenValueNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() ->
|
||||
OAuth2TokenMetadata.builder()
|
||||
.metadata("name", null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetadataWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> OAuth2TokenMetadata.builder().build().getMetadata(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenDefaultThenDefaultsAreSet() {
|
||||
OAuth2TokenMetadata tokenMetadata = OAuth2TokenMetadata.builder().build();
|
||||
assertThat(tokenMetadata.getMetadata()).hasSize(1);
|
||||
assertThat(tokenMetadata.isInvalidated()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenMetadataProvidedThenMetadataIsSet() {
|
||||
OAuth2TokenMetadata tokenMetadata = OAuth2TokenMetadata.builder()
|
||||
.invalidated()
|
||||
.metadata("name1", "value1")
|
||||
.metadata(metadata -> metadata.put("name2", "value2"))
|
||||
.build();
|
||||
assertThat(tokenMetadata.getMetadata()).hasSize(3);
|
||||
assertThat(tokenMetadata.isInvalidated()).isTrue();
|
||||
assertThat(tokenMetadata.<String>getMetadata("name1")).isEqualTo("value1");
|
||||
assertThat(tokenMetadata.<String>getMetadata("name2")).isEqualTo("value2");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.token;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link OAuth2Tokens}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class OAuth2TokensTests {
|
||||
private OAuth2AccessToken accessToken;
|
||||
private OAuth2RefreshToken refreshToken;
|
||||
private OidcIdToken idToken;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Instant issuedAt = Instant.now();
|
||||
this.accessToken = new OAuth2AccessToken(
|
||||
OAuth2AccessToken.TokenType.BEARER,
|
||||
"access-token",
|
||||
issuedAt,
|
||||
issuedAt.plus(Duration.ofMinutes(5)),
|
||||
new HashSet<>(Arrays.asList("read", "write")));
|
||||
this.refreshToken = new OAuth2RefreshToken(
|
||||
"refresh-token",
|
||||
issuedAt);
|
||||
this.idToken = OidcIdToken.withTokenValue("id-token")
|
||||
.issuer("https://provider.com")
|
||||
.subject("subject")
|
||||
.issuedAt(issuedAt)
|
||||
.expiresAt(issuedAt.plus(Duration.ofMinutes(30)))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessTokenWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().accessToken(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("token cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshTokenWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().refreshToken(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("token cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tokenWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().token(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("token cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTokenWhenTokenTypeNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().build().getToken(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("tokenType cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTokenMetadataWhenTokenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().build().getTokenMetadata(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("token cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenTokenMetadataNotProvidedThenDefaultsAreSet() {
|
||||
OAuth2Tokens tokens = OAuth2Tokens.builder()
|
||||
.accessToken(this.accessToken)
|
||||
.refreshToken(this.refreshToken)
|
||||
.token(this.idToken)
|
||||
.build();
|
||||
|
||||
assertThat(tokens.getAccessToken()).isEqualTo(this.accessToken);
|
||||
OAuth2TokenMetadata tokenMetadata = tokens.getTokenMetadata(tokens.getAccessToken());
|
||||
assertThat(tokenMetadata.isInvalidated()).isFalse();
|
||||
|
||||
assertThat(tokens.getRefreshToken()).isEqualTo(this.refreshToken);
|
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getRefreshToken());
|
||||
assertThat(tokenMetadata.isInvalidated()).isFalse();
|
||||
|
||||
assertThat(tokens.getToken(OidcIdToken.class)).isEqualTo(this.idToken);
|
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class));
|
||||
assertThat(tokenMetadata.isInvalidated()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenTokenMetadataProvidedThenTokenMetadataIsSet() {
|
||||
OAuth2TokenMetadata expectedTokenMetadata = OAuth2TokenMetadata.builder().build();
|
||||
OAuth2Tokens tokens = OAuth2Tokens.builder()
|
||||
.accessToken(this.accessToken, expectedTokenMetadata)
|
||||
.refreshToken(this.refreshToken, expectedTokenMetadata)
|
||||
.token(this.idToken, expectedTokenMetadata)
|
||||
.build();
|
||||
|
||||
assertThat(tokens.getAccessToken()).isEqualTo(this.accessToken);
|
||||
OAuth2TokenMetadata tokenMetadata = tokens.getTokenMetadata(tokens.getAccessToken());
|
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata);
|
||||
|
||||
assertThat(tokens.getRefreshToken()).isEqualTo(this.refreshToken);
|
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getRefreshToken());
|
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata);
|
||||
|
||||
assertThat(tokens.getToken(OidcIdToken.class)).isEqualTo(this.idToken);
|
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class));
|
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTokenMetadataWhenTokenNotFoundThenNull() {
|
||||
OAuth2TokenMetadata expectedTokenMetadata = OAuth2TokenMetadata.builder().build();
|
||||
OAuth2Tokens tokens = OAuth2Tokens.builder()
|
||||
.accessToken(this.accessToken, expectedTokenMetadata)
|
||||
.build();
|
||||
|
||||
assertThat(tokens.getAccessToken()).isEqualTo(this.accessToken);
|
||||
OAuth2TokenMetadata tokenMetadata = tokens.getTokenMetadata(tokens.getAccessToken());
|
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata);
|
||||
|
||||
OAuth2AccessToken otherAccessToken = new OAuth2AccessToken(
|
||||
this.accessToken.getTokenType(),
|
||||
"other-access-token",
|
||||
this.accessToken.getIssuedAt(),
|
||||
this.accessToken.getExpiresAt(),
|
||||
this.accessToken.getScopes());
|
||||
assertThat(tokens.getTokenMetadata(otherAccessToken)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidateWhenAllTokensThenAllInvalidated() {
|
||||
OAuth2Tokens tokens = OAuth2Tokens.builder()
|
||||
.accessToken(this.accessToken)
|
||||
.refreshToken(this.refreshToken)
|
||||
.token(this.idToken)
|
||||
.build();
|
||||
tokens.invalidate();
|
||||
|
||||
assertThat(tokens.getTokenMetadata(tokens.getAccessToken()).isInvalidated()).isTrue();
|
||||
assertThat(tokens.getTokenMetadata(tokens.getRefreshToken()).isInvalidated()).isTrue();
|
||||
assertThat(tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class)).isInvalidated()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidateWhenTokenProvidedThenInvalidated() {
|
||||
OAuth2Tokens tokens = OAuth2Tokens.builder()
|
||||
.accessToken(this.accessToken)
|
||||
.refreshToken(this.refreshToken)
|
||||
.token(this.idToken)
|
||||
.build();
|
||||
tokens.invalidate(this.accessToken);
|
||||
|
||||
assertThat(tokens.getTokenMetadata(tokens.getAccessToken()).isInvalidated()).isTrue();
|
||||
assertThat(tokens.getTokenMetadata(tokens.getRefreshToken()).isInvalidated()).isFalse();
|
||||
assertThat(tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class)).isInvalidated()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -755,7 +755,7 @@ public class OAuth2AuthorizationEndpointFilterTests {
|
||||
OAuth2Authorization updatedAuthorization = authorizationCaptor.getValue();
|
||||
assertThat(updatedAuthorization.getRegisteredClientId()).isEqualTo(registeredClient.getId());
|
||||
assertThat(updatedAuthorization.getPrincipalName()).isEqualTo(this.authentication.getPrincipal().toString());
|
||||
assertThat(updatedAuthorization.getAccessToken()).isNotNull();
|
||||
assertThat(updatedAuthorization.getTokens().getAccessToken()).isNotNull();
|
||||
assertThat(updatedAuthorization.<String>getAttribute(OAuth2AuthorizationAttributeNames.STATE)).isNull();
|
||||
assertThat(updatedAuthorization.<String>getAttribute(OAuth2AuthorizationAttributeNames.CODE)).isNotNull();
|
||||
assertThat(updatedAuthorization.<OAuth2AuthorizationRequest>getAttribute(OAuth2AuthorizationAttributeNames.AUTHORIZATION_REQUEST))
|
||||
|
||||
Reference in New Issue
Block a user