From 3ff825576b5fc44263d1ad26ad674b554d67d904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Kov=C3=A1=C4=8D?= Date: Sat, 12 Jun 2021 01:33:00 +0200 Subject: [PATCH] Move and rename OAuth2IntrospectionClaimAccessor/Names Introduced OAuth2TokenIntrospectionClaimAccessor and OAuth2TokenIntrospectionClaimNames with copied implementation from OAuth2IntrospectionClaimAccessor/Names. OAuth2IntrospectionClaimAccessor and OAuth2IntrospectionClaimNames are now deprecated. Also method getScopes() returning list of scopes was introduced and getScope() is now deprecated. Closes gh-9647 --- etc/checkstyle/checkstyle-suppressions.xml | 1 + ...OAuth2TokenIntrospectionClaimAccessor.java | 150 +++++++++++++ .../OAuth2TokenIntrospectionClaimNames.java | 96 +++++++++ ...2TokenIntrospectionClaimAccessorTests.java | 197 ++++++++++++++++++ .../OpaqueTokenAuthenticationProvider.java | 8 +- ...queTokenReactiveAuthenticationManager.java | 8 +- .../NimbusOpaqueTokenIntrospector.java | 17 +- ...NimbusReactiveOpaqueTokenIntrospector.java | 17 +- .../OAuth2IntrospectionClaimAccessor.java | 110 +--------- .../OAuth2IntrospectionClaimNames.java | 57 ++--- .../TestOAuth2AuthenticatedPrincipals.java | 21 +- .../BearerTokenAuthenticationTests.java | 12 +- ...paqueTokenAuthenticationProviderTests.java | 24 +-- ...kenReactiveAuthenticationManagerTests.java | 24 +-- .../NimbusOpaqueTokenIntrospectorTests.java | 35 ++-- ...sReactiveOpaqueTokenIntrospectorTests.java | 33 +-- .../server/SecurityMockServerConfigurers.java | 8 +- .../SecurityMockMvcRequestPostProcessors.java | 10 +- ...yMockServerConfigurerOpaqueTokenTests.java | 20 +- 19 files changed, 592 insertions(+), 256 deletions(-) create mode 100644 oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessor.java create mode 100644 oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimNames.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessorTests.java diff --git a/etc/checkstyle/checkstyle-suppressions.xml b/etc/checkstyle/checkstyle-suppressions.xml index 6f58307877..cd90b3cd04 100644 --- a/etc/checkstyle/checkstyle-suppressions.xml +++ b/etc/checkstyle/checkstyle-suppressions.xml @@ -27,6 +27,7 @@ + diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessor.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessor.java new file mode 100644 index 0000000000..e253b8b58f --- /dev/null +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessor.java @@ -0,0 +1,150 @@ +/* + * Copyright 2002-2021 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.core; + +import java.net.URL; +import java.time.Instant; +import java.util.List; + +import org.springframework.lang.Nullable; + +/** + * A {@link ClaimAccessor} for the "claims" that may be contained in the + * Introspection Response. + * + * @author David Kovac + * @since 5.6 + * @see ClaimAccessor + * @see OAuth2TokenIntrospectionClaimNames + * @see Introspection Response + */ +public interface OAuth2TokenIntrospectionClaimAccessor extends ClaimAccessor { + + /** + * Returns the indicator {@code (active)} whether or not the token is currently active + * @return the indicator whether or not the token is currently active + */ + default boolean isActive() { + return Boolean.TRUE.equals(getClaimAsBoolean(OAuth2TokenIntrospectionClaimNames.ACTIVE)); + } + + /** + * Returns a human-readable identifier {@code (username)} for the resource owner that + * authorized the token + * @return a human-readable identifier for the resource owner that authorized the + * token + */ + @Nullable + default String getUsername() { + return getClaimAsString(OAuth2TokenIntrospectionClaimNames.USERNAME); + } + + /** + * Returns the client identifier {@code (client_id)} for the token + * @return the client identifier for the token + */ + @Nullable + default String getClientId() { + return getClaimAsString(OAuth2TokenIntrospectionClaimNames.CLIENT_ID); + } + + /** + * Returns the scopes {@code (scope)} associated with the token + * @return the scopes associated with the token + */ + @Nullable + default List getScopes() { + return getClaimAsStringList(OAuth2TokenIntrospectionClaimNames.SCOPE); + } + + /** + * Returns the type of the token {@code (token_type)}, for example {@code bearer}. + * @return the type of the token, for example {@code bearer}. + */ + @Nullable + default String getTokenType() { + return getClaimAsString(OAuth2TokenIntrospectionClaimNames.TOKEN_TYPE); + } + + /** + * Returns a timestamp {@code (exp)} indicating when the token expires + * @return a timestamp indicating when the token expires + */ + @Nullable + default Instant getExpiresAt() { + return getClaimAsInstant(OAuth2TokenIntrospectionClaimNames.EXP); + } + + /** + * Returns a timestamp {@code (iat)} indicating when the token was issued + * @return a timestamp indicating when the token was issued + */ + @Nullable + default Instant getIssuedAt() { + return getClaimAsInstant(OAuth2TokenIntrospectionClaimNames.IAT); + } + + /** + * Returns a timestamp {@code (nbf)} indicating when the token is not to be used + * before + * @return a timestamp indicating when the token is not to be used before + */ + @Nullable + default Instant getNotBefore() { + return getClaimAsInstant(OAuth2TokenIntrospectionClaimNames.NBF); + } + + /** + * Returns usually a machine-readable identifier {@code (sub)} of the resource owner + * who authorized the token + * @return usually a machine-readable identifier of the resource owner who authorized + * the token + */ + @Nullable + default String getSubject() { + return getClaimAsString(OAuth2TokenIntrospectionClaimNames.SUB); + } + + /** + * Returns the intended audience {@code (aud)} for the token + * @return the intended audience for the token + */ + @Nullable + default List getAudience() { + return getClaimAsStringList(OAuth2TokenIntrospectionClaimNames.AUD); + } + + /** + * Returns the issuer {@code (iss)} of the token + * @return the issuer of the token + */ + @Nullable + default URL getIssuer() { + return getClaimAsURL(OAuth2TokenIntrospectionClaimNames.ISS); + } + + /** + * Returns the identifier {@code (jti)} for the token + * @return the identifier for the token + */ + @Nullable + default String getId() { + return getClaimAsString(OAuth2TokenIntrospectionClaimNames.JTI); + } + +} diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimNames.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimNames.java new file mode 100644 index 0000000000..ceedbd6420 --- /dev/null +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimNames.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002-2021 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.core; + +/** + * The names of the "Introspection Claims" defined by an + * Introspection + * Response. + * + * @author Josh Cummings + * @since 5.6 + * @see OAuth + * 2.0 Token Introspection (RFC7662) + * @see OAuth + * Parameters (IANA) + */ +public interface OAuth2TokenIntrospectionClaimNames { + + /** + * {@code active} - Indicator whether or not the token is currently active + */ + String ACTIVE = "active"; + + /** + * {@code username} - A human-readable identifier for the resource owner that + * authorized the token + */ + String USERNAME = "username"; + + /** + * {@code client_id} - The Client identifier for the token + */ + String CLIENT_ID = "client_id"; + + /** + * {@code scope} - The scopes for the token + */ + String SCOPE = "scope"; + + /** + * {@code token_type} - The type of the token, for example {@code bearer}. + */ + String TOKEN_TYPE = "token_type"; + + /** + * {@code exp} - A timestamp indicating when the token expires + */ + String EXP = "exp"; + + /** + * {@code iat} - A timestamp indicating when the token was issued + */ + String IAT = "iat"; + + /** + * {@code nbf} - A timestamp indicating when the token is not to be used before + */ + String NBF = "nbf"; + + /** + * {@code sub} - Usually a machine-readable identifier of the resource owner who + * authorized the token + */ + String SUB = "sub"; + + /** + * {@code aud} - The intended audience for the token + */ + String AUD = "aud"; + + /** + * {@code iss} - The issuer of the token + */ + String ISS = "iss"; + + /** + * {@code jti} - The identifier for the token + */ + String JTI = "jti"; + +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessorTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessorTests.java new file mode 100644 index 0000000000..bd0ea50923 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2TokenIntrospectionClaimAccessorTests.java @@ -0,0 +1,197 @@ +/* + * Copyright 2002-2021 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.core; + +import java.net.MalformedURLException; +import java.net.URL; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OAuth2TokenIntrospectionClaimAccessor}. + * + * @author David Kovac + */ +public class OAuth2TokenIntrospectionClaimAccessorTests { + + private final Map claims = new HashMap<>(); + + private final OAuth2TokenIntrospectionClaimAccessor claimAccessor = (() -> this.claims); + + @BeforeEach + public void setup() { + this.claims.clear(); + } + + @Test + public void isActiveWhenActiveClaimNotExistingThenReturnFalse() { + assertThat(this.claimAccessor.isActive()).isFalse(); + } + + @Test + public void isActiveWhenActiveClaimValueIsNullThenReturnFalse() { + this.claims.put(OAuth2TokenIntrospectionClaimNames.ACTIVE, null); + assertThat(this.claimAccessor.isActive()).isFalse(); + } + + @Test + public void isActiveWhenActiveClaimValueIsTrueThenReturnTrue() { + this.claims.put(OAuth2TokenIntrospectionClaimNames.ACTIVE, "true"); + assertThat(this.claimAccessor.isActive()).isTrue(); + } + + @Test + public void getUsernameWhenUsernameClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getUsername()).isNull(); + } + + @Test + public void getUsernameWhenUsernameClaimExistingThenReturnUsername() { + String expectedUsernameValue = "username"; + this.claims.put(OAuth2TokenIntrospectionClaimNames.USERNAME, expectedUsernameValue); + assertThat(this.claimAccessor.getUsername()).isEqualTo(expectedUsernameValue); + } + + @Test + public void getClientIdWhenClientIdClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getUsername()).isNull(); + } + + @Test + public void getClientIdWhenClientIdClaimExistingThenReturnClientId() { + String expectedClientIdValue = "clientId"; + this.claims.put(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, expectedClientIdValue); + assertThat(this.claimAccessor.getClientId()).isEqualTo(expectedClientIdValue); + } + + @Test + public void getScopesWhenScopeClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getScopes()).isNull(); + } + + @Test + public void getScopesWhenScopeClaimExistingThenReturnScope() { + List expectedScopeValue = Arrays.asList("scope1", "scope2"); + this.claims.put(OAuth2TokenIntrospectionClaimNames.SCOPE, expectedScopeValue); + assertThat(this.claimAccessor.getScopes()).hasSameElementsAs(expectedScopeValue); + } + + @Test + public void getTokenTypeWhenTokenTypeClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getTokenType()).isNull(); + } + + @Test + public void getTokenTypeWhenTokenTypeClaimExistingThenReturnTokenType() { + String expectedTokenTypeValue = "tokenType"; + this.claims.put(OAuth2TokenIntrospectionClaimNames.TOKEN_TYPE, expectedTokenTypeValue); + assertThat(this.claimAccessor.getTokenType()).isEqualTo(expectedTokenTypeValue); + } + + @Test + public void getExpiresAtWhenExpiresAtClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getExpiresAt()).isNull(); + } + + @Test + public void getExpiresAtWhenExpiresAtClaimExistingThenReturnExpiresAt() { + Instant expectedExpiresAtValue = Instant.now(); + this.claims.put(OAuth2TokenIntrospectionClaimNames.EXP, expectedExpiresAtValue); + assertThat(this.claimAccessor.getExpiresAt()).isEqualTo(expectedExpiresAtValue); + } + + @Test + public void getIssuedAtWhenIssuedAtClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getExpiresAt()).isNull(); + } + + @Test + public void getIssuedAtWhenIssuedAtClaimExistingThenReturnIssuedAt() { + Instant expectedIssuedAtValue = Instant.now(); + this.claims.put(OAuth2TokenIntrospectionClaimNames.IAT, expectedIssuedAtValue); + assertThat(this.claimAccessor.getIssuedAt()).isEqualTo(expectedIssuedAtValue); + } + + @Test + public void getNotBeforeWhenNotBeforeClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getNotBefore()).isNull(); + } + + @Test + public void getNotBeforeWhenNotBeforeClaimExistingThenReturnNotBefore() { + Instant expectedNotBeforeValue = Instant.now(); + this.claims.put(OAuth2TokenIntrospectionClaimNames.NBF, expectedNotBeforeValue); + assertThat(this.claimAccessor.getNotBefore()).isEqualTo(expectedNotBeforeValue); + } + + @Test + public void getSubjectWhenSubjectClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getSubject()).isNull(); + } + + @Test + public void getSubjectWhenSubjectClaimExistingThenReturnSubject() { + String expectedSubjectValue = "subject"; + this.claims.put(OAuth2TokenIntrospectionClaimNames.SUB, expectedSubjectValue); + assertThat(this.claimAccessor.getSubject()).isEqualTo(expectedSubjectValue); + } + + @Test + public void getAudienceWhenAudienceClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getAudience()).isNull(); + } + + @Test + public void getAudienceWhenAudienceClaimExistingThenReturnAudience() { + List expectedAudienceValue = Arrays.asList("audience1", "audience2"); + this.claims.put(OAuth2TokenIntrospectionClaimNames.AUD, expectedAudienceValue); + assertThat(this.claimAccessor.getAudience()).hasSameElementsAs(expectedAudienceValue); + } + + @Test + public void getIssuerWhenIssuerClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getIssuer()).isNull(); + } + + @Test + public void getIssuerWhenIssuerClaimExistingThenReturnIssuer() throws MalformedURLException { + URL expectedIssuerValue = new URL("https://issuer.com"); + this.claims.put(OAuth2TokenIntrospectionClaimNames.ISS, expectedIssuerValue); + assertThat(this.claimAccessor.getIssuer()).isEqualTo(expectedIssuerValue); + } + + @Test + public void getIdWhenJtiClaimNotExistingThenReturnNull() { + assertThat(this.claimAccessor.getId()).isNull(); + } + + @Test + public void getIdWhenJtiClaimExistingThenReturnId() { + String expectedIdValue = "id"; + this.claims.put(OAuth2TokenIntrospectionClaimNames.JTI, expectedIdValue); + assertThat(this.claimAccessor.getId()).isEqualTo(expectedIdValue); + } + +} diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java index d754424531..fec9821e9f 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -30,10 +30,10 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException; import org.springframework.security.oauth2.server.resource.introspection.BadOpaqueTokenException; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; import org.springframework.util.Assert; @@ -117,8 +117,8 @@ public final class OpaqueTokenAuthenticationProvider implements AuthenticationPr } private AbstractAuthenticationToken convert(OAuth2AuthenticatedPrincipal principal, String token) { - Instant iat = principal.getAttribute(OAuth2IntrospectionClaimNames.ISSUED_AT); - Instant exp = principal.getAttribute(OAuth2IntrospectionClaimNames.EXPIRES_AT); + Instant iat = principal.getAttribute(OAuth2TokenIntrospectionClaimNames.IAT); + Instant exp = principal.getAttribute(OAuth2TokenIntrospectionClaimNames.EXP); OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, token, iat, exp); return new BearerTokenAuthentication(principal, accessToken, principal.getAuthorities()); } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java index ad2d848241..d3c62c0dd9 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -27,10 +27,10 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException; import org.springframework.security.oauth2.server.resource.introspection.BadOpaqueTokenException; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector; import org.springframework.util.Assert; @@ -89,8 +89,8 @@ public class OpaqueTokenReactiveAuthenticationManager implements ReactiveAuthent // @formatter:off return this.introspector.introspect(token) .map((principal) -> { - Instant iat = principal.getAttribute(OAuth2IntrospectionClaimNames.ISSUED_AT); - Instant exp = principal.getAttribute(OAuth2IntrospectionClaimNames.EXPIRES_AT); + Instant iat = principal.getAttribute(OAuth2TokenIntrospectionClaimNames.IAT); + Instant exp = principal.getAttribute(OAuth2TokenIntrospectionClaimNames.EXP); // construct token OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, token, iat, exp); return new BearerTokenAuthentication(principal, accessToken, principal.getAuthorities()); diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospector.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospector.java index 51fe7d0df6..830ec77ee5 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospector.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospector.java @@ -42,6 +42,7 @@ import org.springframework.http.client.support.BasicAuthenticationInterceptor; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -192,28 +193,28 @@ public class NimbusOpaqueTokenIntrospector implements OpaqueTokenIntrospector { for (Audience audience : response.getAudience()) { audiences.add(audience.getValue()); } - claims.put(OAuth2IntrospectionClaimNames.AUDIENCE, Collections.unmodifiableList(audiences)); + claims.put(OAuth2TokenIntrospectionClaimNames.AUD, Collections.unmodifiableList(audiences)); } if (response.getClientID() != null) { - claims.put(OAuth2IntrospectionClaimNames.CLIENT_ID, response.getClientID().getValue()); + claims.put(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, response.getClientID().getValue()); } if (response.getExpirationTime() != null) { Instant exp = response.getExpirationTime().toInstant(); - claims.put(OAuth2IntrospectionClaimNames.EXPIRES_AT, exp); + claims.put(OAuth2TokenIntrospectionClaimNames.EXP, exp); } if (response.getIssueTime() != null) { Instant iat = response.getIssueTime().toInstant(); - claims.put(OAuth2IntrospectionClaimNames.ISSUED_AT, iat); + claims.put(OAuth2TokenIntrospectionClaimNames.IAT, iat); } if (response.getIssuer() != null) { - claims.put(OAuth2IntrospectionClaimNames.ISSUER, issuer(response.getIssuer().getValue())); + claims.put(OAuth2TokenIntrospectionClaimNames.ISS, issuer(response.getIssuer().getValue())); } if (response.getNotBeforeTime() != null) { - claims.put(OAuth2IntrospectionClaimNames.NOT_BEFORE, response.getNotBeforeTime().toInstant()); + claims.put(OAuth2TokenIntrospectionClaimNames.NBF, response.getNotBeforeTime().toInstant()); } if (response.getScope() != null) { List scopes = Collections.unmodifiableList(response.getScope().toStringList()); - claims.put(OAuth2IntrospectionClaimNames.SCOPE, scopes); + claims.put(OAuth2TokenIntrospectionClaimNames.SCOPE, scopes); for (String scope : scopes) { authorities.add(new SimpleGrantedAuthority(this.authorityPrefix + scope)); } @@ -227,7 +228,7 @@ public class NimbusOpaqueTokenIntrospector implements OpaqueTokenIntrospector { } catch (Exception ex) { throw new OAuth2IntrospectionException( - "Invalid " + OAuth2IntrospectionClaimNames.ISSUER + " value: " + uri); + "Invalid " + OAuth2TokenIntrospectionClaimNames.ISS + " value: " + uri); } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java index 670f6a3ac5..b562c86308 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java @@ -38,6 +38,7 @@ import org.springframework.http.MediaType; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.util.Assert; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.ClientResponse; @@ -159,28 +160,28 @@ public class NimbusReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke for (Audience audience : response.getAudience()) { audiences.add(audience.getValue()); } - claims.put(OAuth2IntrospectionClaimNames.AUDIENCE, Collections.unmodifiableList(audiences)); + claims.put(OAuth2TokenIntrospectionClaimNames.AUD, Collections.unmodifiableList(audiences)); } if (response.getClientID() != null) { - claims.put(OAuth2IntrospectionClaimNames.CLIENT_ID, response.getClientID().getValue()); + claims.put(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, response.getClientID().getValue()); } if (response.getExpirationTime() != null) { Instant exp = response.getExpirationTime().toInstant(); - claims.put(OAuth2IntrospectionClaimNames.EXPIRES_AT, exp); + claims.put(OAuth2TokenIntrospectionClaimNames.EXP, exp); } if (response.getIssueTime() != null) { Instant iat = response.getIssueTime().toInstant(); - claims.put(OAuth2IntrospectionClaimNames.ISSUED_AT, iat); + claims.put(OAuth2TokenIntrospectionClaimNames.IAT, iat); } if (response.getIssuer() != null) { - claims.put(OAuth2IntrospectionClaimNames.ISSUER, issuer(response.getIssuer().getValue())); + claims.put(OAuth2TokenIntrospectionClaimNames.ISS, issuer(response.getIssuer().getValue())); } if (response.getNotBeforeTime() != null) { - claims.put(OAuth2IntrospectionClaimNames.NOT_BEFORE, response.getNotBeforeTime().toInstant()); + claims.put(OAuth2TokenIntrospectionClaimNames.NBF, response.getNotBeforeTime().toInstant()); } if (response.getScope() != null) { List scopes = Collections.unmodifiableList(response.getScope().toStringList()); - claims.put(OAuth2IntrospectionClaimNames.SCOPE, scopes); + claims.put(OAuth2TokenIntrospectionClaimNames.SCOPE, scopes); for (String scope : scopes) { authorities.add(new SimpleGrantedAuthority(this.authorityPrefix + scope)); @@ -195,7 +196,7 @@ public class NimbusReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke } catch (Exception ex) { throw new OAuth2IntrospectionException( - "Invalid " + OAuth2IntrospectionClaimNames.ISSUER + " value: " + uri); + "Invalid " + OAuth2TokenIntrospectionClaimNames.ISS + " value: " + uri); } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimAccessor.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimAccessor.java index b95109d670..ca04d23849 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimAccessor.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -16,16 +16,16 @@ package org.springframework.security.oauth2.server.resource.introspection; -import java.net.URL; -import java.time.Instant; -import java.util.List; - +import org.springframework.lang.Nullable; import org.springframework.security.oauth2.core.ClaimAccessor; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimAccessor; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; /** * A {@link ClaimAccessor} for the "claims" that may be contained in the * Introspection Response. * + * @deprecated Use {@link OAuth2TokenIntrospectionClaimAccessor} instead * @author David Kovac * @since 5.4 * @see ClaimAccessor @@ -34,107 +34,17 @@ import org.springframework.security.oauth2.core.ClaimAccessor; * @see Introspection Response */ -public interface OAuth2IntrospectionClaimAccessor extends ClaimAccessor { - - /** - * Returns the indicator {@code (active)} whether or not the token is currently active - * @return the indicator whether or not the token is currently active - */ - default boolean isActive() { - return Boolean.TRUE.equals(this.getClaimAsBoolean(OAuth2IntrospectionClaimNames.ACTIVE)); - } +@Deprecated +public interface OAuth2IntrospectionClaimAccessor extends OAuth2TokenIntrospectionClaimAccessor { /** * Returns the scopes {@code (scope)} associated with the token * @return the scopes associated with the token + * @deprecated Since 5.6. Use {@link #getScopes()} instead */ + @Nullable default String getScope() { - return this.getClaimAsString(OAuth2IntrospectionClaimNames.SCOPE); - } - - /** - * Returns the client identifier {@code (client_id)} for the token - * @return the client identifier for the token - */ - default String getClientId() { - return this.getClaimAsString(OAuth2IntrospectionClaimNames.CLIENT_ID); - } - - /** - * Returns a human-readable identifier {@code (username)} for the resource owner that - * authorized the token - * @return a human-readable identifier for the resource owner that authorized the - * token - */ - default String getUsername() { - return this.getClaimAsString(OAuth2IntrospectionClaimNames.USERNAME); - } - - /** - * Returns the type of the token {@code (token_type)}, for example {@code bearer}. - * @return the type of the token, for example {@code bearer}. - */ - default String getTokenType() { - return this.getClaimAsString(OAuth2IntrospectionClaimNames.TOKEN_TYPE); - } - - /** - * Returns a timestamp {@code (exp)} indicating when the token expires - * @return a timestamp indicating when the token expires - */ - default Instant getExpiresAt() { - return this.getClaimAsInstant(OAuth2IntrospectionClaimNames.EXPIRES_AT); - } - - /** - * Returns a timestamp {@code (iat)} indicating when the token was issued - * @return a timestamp indicating when the token was issued - */ - default Instant getIssuedAt() { - return this.getClaimAsInstant(OAuth2IntrospectionClaimNames.ISSUED_AT); - } - - /** - * Returns a timestamp {@code (nbf)} indicating when the token is not to be used - * before - * @return a timestamp indicating when the token is not to be used before - */ - default Instant getNotBefore() { - return this.getClaimAsInstant(OAuth2IntrospectionClaimNames.NOT_BEFORE); - } - - /** - * Returns usually a machine-readable identifier {@code (sub)} of the resource owner - * who authorized the token - * @return usually a machine-readable identifier of the resource owner who authorized - * the token - */ - default String getSubject() { - return this.getClaimAsString(OAuth2IntrospectionClaimNames.SUBJECT); - } - - /** - * Returns the intended audience {@code (aud)} for the token - * @return the intended audience for the token - */ - default List getAudience() { - return this.getClaimAsStringList(OAuth2IntrospectionClaimNames.AUDIENCE); - } - - /** - * Returns the issuer {@code (iss)} of the token - * @return the issuer of the token - */ - default URL getIssuer() { - return this.getClaimAsURL(OAuth2IntrospectionClaimNames.ISSUER); - } - - /** - * Returns the identifier {@code (jti)} for the token - * @return the identifier for the token - */ - default String getId() { - return this.getClaimAsString(OAuth2IntrospectionClaimNames.JTI); + return getClaimAsString(OAuth2TokenIntrospectionClaimNames.SCOPE); } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimNames.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimNames.java index c21e4bb91a..9e5c8227cd 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimNames.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/OAuth2IntrospectionClaimNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -16,76 +16,55 @@ package org.springframework.security.oauth2.server.resource.introspection; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; + /** * The names of the "Introspection Claims" defined by an * Introspection * Response. * + * @deprecated Use {@link OAuth2TokenIntrospectionClaimNames} instead * @author Josh Cummings * @since 5.2 */ -public interface OAuth2IntrospectionClaimNames { - - /** - * {@code active} - Indicator whether or not the token is currently active - */ - String ACTIVE = "active"; - - /** - * {@code scope} - The scopes for the token - */ - String SCOPE = "scope"; - - /** - * {@code client_id} - The Client identifier for the token - */ - String CLIENT_ID = "client_id"; - - /** - * {@code username} - A human-readable identifier for the resource owner that - * authorized the token - */ - String USERNAME = "username"; - - /** - * {@code token_type} - The type of the token, for example {@code bearer}. - */ - String TOKEN_TYPE = "token_type"; +@Deprecated +public interface OAuth2IntrospectionClaimNames extends OAuth2TokenIntrospectionClaimNames { /** * {@code exp} - A timestamp indicating when the token expires + * @deprecated use {@link #EXP} instead */ - String EXPIRES_AT = "exp"; + String EXPIRES_AT = EXP; /** * {@code iat} - A timestamp indicating when the token was issued + * @deprecated use {@link #IAT} instead */ - String ISSUED_AT = "iat"; + String ISSUED_AT = IAT; /** * {@code nbf} - A timestamp indicating when the token is not to be used before + * @deprecated use {@link #NBF} instead */ - String NOT_BEFORE = "nbf"; + String NOT_BEFORE = NBF; /** * {@code sub} - Usually a machine-readable identifier of the resource owner who * authorized the token + * @deprecated use {@link #SUB} instead */ - String SUBJECT = "sub"; + String SUBJECT = SUB; /** * {@code aud} - The intended audience for the token + * @deprecated use {@link #AUD} instead */ - String AUDIENCE = "aud"; + String AUDIENCE = AUD; /** * {@code iss} - The issuer of the token + * @deprecated use {@link #ISS} instead */ - String ISSUER = "iss"; - - /** - * {@code jti} - The identifier for the token - */ - String JTI = "jti"; + String ISSUER = ISS; } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/core/TestOAuth2AuthenticatedPrincipals.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/core/TestOAuth2AuthenticatedPrincipals.java index 11cfb3bcc7..2f4558738d 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/core/TestOAuth2AuthenticatedPrincipals.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/core/TestOAuth2AuthenticatedPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -29,7 +29,6 @@ import java.util.function.Consumer; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; /** * Test values of {@link OAuth2AuthenticatedPrincipal}s @@ -48,15 +47,15 @@ public final class TestOAuth2AuthenticatedPrincipals { public static OAuth2AuthenticatedPrincipal active(Consumer> attributesConsumer) { Map attributes = new HashMap<>(); - attributes.put(OAuth2IntrospectionClaimNames.ACTIVE, true); - attributes.put(OAuth2IntrospectionClaimNames.AUDIENCE, Arrays.asList("https://protected.example.net/resource")); - attributes.put(OAuth2IntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4"); - attributes.put(OAuth2IntrospectionClaimNames.EXPIRES_AT, Instant.ofEpochSecond(1419356238)); - attributes.put(OAuth2IntrospectionClaimNames.NOT_BEFORE, Instant.ofEpochSecond(29348723984L)); - attributes.put(OAuth2IntrospectionClaimNames.ISSUER, url("https://server.example.com/")); - attributes.put(OAuth2IntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")); - attributes.put(OAuth2IntrospectionClaimNames.SUBJECT, "Z5O3upPC88QrAjx00dis"); - attributes.put(OAuth2IntrospectionClaimNames.USERNAME, "jdoe"); + attributes.put(OAuth2TokenIntrospectionClaimNames.ACTIVE, true); + attributes.put(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("https://protected.example.net/resource")); + attributes.put(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4"); + attributes.put(OAuth2TokenIntrospectionClaimNames.EXP, Instant.ofEpochSecond(1419356238)); + attributes.put(OAuth2TokenIntrospectionClaimNames.NBF, Instant.ofEpochSecond(29348723984L)); + attributes.put(OAuth2TokenIntrospectionClaimNames.ISS, url("https://server.example.com/")); + attributes.put(OAuth2TokenIntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")); + attributes.put(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis"); + attributes.put(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe"); attributesConsumer.accept(attributes); Collection authorities = Arrays.asList(new SimpleGrantedAuthority("SCOPE_read"), new SimpleGrantedAuthority("SCOPE_write"), new SimpleGrantedAuthority("SCOPE_dolphin")); diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java index de6193ec20..9fcffe370f 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -33,7 +33,7 @@ import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -58,9 +58,9 @@ public class BearerTokenAuthenticationTests { @BeforeEach public void setUp() { - this.attributesMap.put(OAuth2IntrospectionClaimNames.SUBJECT, this.name); - this.attributesMap.put(OAuth2IntrospectionClaimNames.CLIENT_ID, "client_id"); - this.attributesMap.put(OAuth2IntrospectionClaimNames.USERNAME, "username"); + this.attributesMap.put(OAuth2TokenIntrospectionClaimNames.SUB, this.name); + this.attributesMap.put(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, "client_id"); + this.attributesMap.put(OAuth2TokenIntrospectionClaimNames.USERNAME, "username"); this.principal = new DefaultOAuth2AuthenticatedPrincipal(this.attributesMap, null); } @@ -86,7 +86,7 @@ public class BearerTokenAuthenticationTests { BearerTokenAuthentication authenticated = new BearerTokenAuthentication(this.principal, this.token, null); // @formatter:off assertThat(authenticated.getName()) - .isEqualTo(this.principal.getAttribute(OAuth2IntrospectionClaimNames.SUBJECT)); + .isEqualTo(this.principal.getAttribute(OAuth2TokenIntrospectionClaimNames.SUB)); // @formatter:on } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java index f5b03b635f..69eaecb9b2 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -27,10 +27,10 @@ import org.junit.jupiter.api.Test; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipals; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; @@ -61,16 +61,16 @@ public class OpaqueTokenAuthenticationProviderTests { // @formatter:off assertThat(attributes) .isNotNull() - .containsEntry(OAuth2IntrospectionClaimNames.ACTIVE, true) - .containsEntry(OAuth2IntrospectionClaimNames.AUDIENCE, + .containsEntry(OAuth2TokenIntrospectionClaimNames.ACTIVE, true) + .containsEntry(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("https://protected.example.net/resource")) - .containsEntry(OAuth2IntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") - .containsEntry(OAuth2IntrospectionClaimNames.EXPIRES_AT, Instant.ofEpochSecond(1419356238)) - .containsEntry(OAuth2IntrospectionClaimNames.ISSUER, new URL("https://server.example.com/")) - .containsEntry(OAuth2IntrospectionClaimNames.NOT_BEFORE, Instant.ofEpochSecond(29348723984L)) - .containsEntry(OAuth2IntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) - .containsEntry(OAuth2IntrospectionClaimNames.SUBJECT, "Z5O3upPC88QrAjx00dis") - .containsEntry(OAuth2IntrospectionClaimNames.USERNAME, "jdoe") + .containsEntry(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") + .containsEntry(OAuth2TokenIntrospectionClaimNames.EXP, Instant.ofEpochSecond(1419356238)) + .containsEntry(OAuth2TokenIntrospectionClaimNames.ISS, new URL("https://server.example.com/")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.NBF, Instant.ofEpochSecond(29348723984L)) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis") + .containsEntry(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe") .containsEntry("extension_field", "twenty-seven"); assertThat(result.getAuthorities()) .extracting("authority") @@ -92,7 +92,7 @@ public class OpaqueTokenAuthenticationProviderTests { // @formatter:off assertThat(attributes) .isNotNull() - .doesNotContainKey(OAuth2IntrospectionClaimNames.SCOPE); + .doesNotContainKey(OAuth2TokenIntrospectionClaimNames.SCOPE); // @formatter:on assertThat(result.getAuthorities()).isEmpty(); } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java index d01e0b08da..7f671a3730 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -28,10 +28,10 @@ import reactor.core.publisher.Mono; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipals; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector; @@ -62,16 +62,16 @@ public class OpaqueTokenReactiveAuthenticationManagerTests { // @formatter:off assertThat(attributes) .isNotNull() - .containsEntry(OAuth2IntrospectionClaimNames.ACTIVE, true) - .containsEntry(OAuth2IntrospectionClaimNames.AUDIENCE, + .containsEntry(OAuth2TokenIntrospectionClaimNames.ACTIVE, true) + .containsEntry(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("https://protected.example.net/resource")) - .containsEntry(OAuth2IntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") - .containsEntry(OAuth2IntrospectionClaimNames.EXPIRES_AT, Instant.ofEpochSecond(1419356238)) - .containsEntry(OAuth2IntrospectionClaimNames.ISSUER, new URL("https://server.example.com/")) - .containsEntry(OAuth2IntrospectionClaimNames.NOT_BEFORE, Instant.ofEpochSecond(29348723984L)) - .containsEntry(OAuth2IntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) - .containsEntry(OAuth2IntrospectionClaimNames.SUBJECT, "Z5O3upPC88QrAjx00dis") - .containsEntry(OAuth2IntrospectionClaimNames.USERNAME, "jdoe") + .containsEntry(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") + .containsEntry(OAuth2TokenIntrospectionClaimNames.EXP, Instant.ofEpochSecond(1419356238)) + .containsEntry(OAuth2TokenIntrospectionClaimNames.ISS, new URL("https://server.example.com/")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.NBF, Instant.ofEpochSecond(29348723984L)) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis") + .containsEntry(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe") .containsEntry("extension_field", "twenty-seven"); assertThat(result.getAuthorities()) .extracting("authority") @@ -90,7 +90,7 @@ public class OpaqueTokenReactiveAuthenticationManagerTests { Authentication result = provider.authenticate(new BearerTokenAuthenticationToken("token")).block(); assertThat(result.getPrincipal()).isInstanceOf(OAuth2IntrospectionAuthenticatedPrincipal.class); Map attributes = ((OAuth2AuthenticatedPrincipal) result.getPrincipal()).getAttributes(); - assertThat(attributes).isNotNull().doesNotContainKey(OAuth2IntrospectionClaimNames.SCOPE); + assertThat(attributes).isNotNull().doesNotContainKey(OAuth2TokenIntrospectionClaimNames.SCOPE); assertThat(result.getAuthorities()).isEmpty(); } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospectorTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospectorTests.java index eecb4dab8b..89215cefbe 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospectorTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospectorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -40,6 +40,7 @@ import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.web.client.RestOperations; import static org.assertj.core.api.Assertions.assertThat; @@ -140,15 +141,15 @@ public class NimbusOpaqueTokenIntrospectorTests { // @formatter:off assertThat(authority.getAttributes()) .isNotNull() - .containsEntry(OAuth2IntrospectionClaimNames.ACTIVE, true) - .containsEntry(OAuth2IntrospectionClaimNames.AUDIENCE, + .containsEntry(OAuth2TokenIntrospectionClaimNames.ACTIVE, true) + .containsEntry(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("https://protected.example.net/resource")) - .containsEntry(OAuth2IntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") - .containsEntry(OAuth2IntrospectionClaimNames.EXPIRES_AT, Instant.ofEpochSecond(1419356238)) - .containsEntry(OAuth2IntrospectionClaimNames.ISSUER, new URL("https://server.example.com/")) - .containsEntry(OAuth2IntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) - .containsEntry(OAuth2IntrospectionClaimNames.SUBJECT, "Z5O3upPC88QrAjx00dis") - .containsEntry(OAuth2IntrospectionClaimNames.USERNAME, "jdoe") + .containsEntry(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") + .containsEntry(OAuth2TokenIntrospectionClaimNames.EXP, Instant.ofEpochSecond(1419356238)) + .containsEntry(OAuth2TokenIntrospectionClaimNames.ISS, new URL("https://server.example.com/")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis") + .containsEntry(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe") .containsEntry("extension_field", "twenty-seven"); // @formatter:on } @@ -182,9 +183,9 @@ public class NimbusOpaqueTokenIntrospectorTests { @Test public void introspectWhenActiveTokenThenParsesValuesInResponse() { Map introspectedValues = new HashMap<>(); - introspectedValues.put(OAuth2IntrospectionClaimNames.ACTIVE, true); - introspectedValues.put(OAuth2IntrospectionClaimNames.AUDIENCE, Arrays.asList("aud")); - introspectedValues.put(OAuth2IntrospectionClaimNames.NOT_BEFORE, 29348723984L); + introspectedValues.put(OAuth2TokenIntrospectionClaimNames.ACTIVE, true); + introspectedValues.put(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("aud")); + introspectedValues.put(OAuth2TokenIntrospectionClaimNames.NBF, 29348723984L); RestOperations restOperations = mock(RestOperations.class); OpaqueTokenIntrospector introspectionClient = new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations); @@ -194,11 +195,11 @@ public class NimbusOpaqueTokenIntrospectorTests { // @formatter:off assertThat(authority.getAttributes()) .isNotNull() - .containsEntry(OAuth2IntrospectionClaimNames.ACTIVE, true) - .containsEntry(OAuth2IntrospectionClaimNames.AUDIENCE, Arrays.asList("aud")) - .containsEntry(OAuth2IntrospectionClaimNames.NOT_BEFORE, Instant.ofEpochSecond(29348723984L)) - .doesNotContainKey(OAuth2IntrospectionClaimNames.CLIENT_ID) - .doesNotContainKey(OAuth2IntrospectionClaimNames.SCOPE); + .containsEntry(OAuth2TokenIntrospectionClaimNames.ACTIVE, true) + .containsEntry(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("aud")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.NBF, Instant.ofEpochSecond(29348723984L)) + .doesNotContainKey(OAuth2TokenIntrospectionClaimNames.CLIENT_ID) + .doesNotContainKey(OAuth2TokenIntrospectionClaimNames.SCOPE); // @formatter:on } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java index b1306d10e9..e299d9be31 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java @@ -37,6 +37,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -111,15 +112,15 @@ public class NimbusReactiveOpaqueTokenIntrospectorTests { // @formatter:off assertThat(authority.getAttributes()) .isNotNull() - .containsEntry(OAuth2IntrospectionClaimNames.ACTIVE, true) - .containsEntry(OAuth2IntrospectionClaimNames.AUDIENCE, + .containsEntry(OAuth2TokenIntrospectionClaimNames.ACTIVE, true) + .containsEntry(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("https://protected.example.net/resource")) - .containsEntry(OAuth2IntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") - .containsEntry(OAuth2IntrospectionClaimNames.EXPIRES_AT, Instant.ofEpochSecond(1419356238)) - .containsEntry(OAuth2IntrospectionClaimNames.ISSUER, new URL("https://server.example.com/")) - .containsEntry(OAuth2IntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) - .containsEntry(OAuth2IntrospectionClaimNames.SUBJECT, "Z5O3upPC88QrAjx00dis") - .containsEntry(OAuth2IntrospectionClaimNames.USERNAME, "jdoe") + .containsEntry(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, "l238j323ds-23ij4") + .containsEntry(OAuth2TokenIntrospectionClaimNames.EXP, Instant.ofEpochSecond(1419356238)) + .containsEntry(OAuth2TokenIntrospectionClaimNames.ISS, new URL("https://server.example.com/")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SCOPE, Arrays.asList("read", "write", "dolphin")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.SUB, "Z5O3upPC88QrAjx00dis") + .containsEntry(OAuth2TokenIntrospectionClaimNames.USERNAME, "jdoe") .containsEntry("extension_field", "twenty-seven"); // @formatter:on } @@ -151,9 +152,9 @@ public class NimbusReactiveOpaqueTokenIntrospectorTests { @Test public void authenticateWhenActiveTokenThenParsesValuesInResponse() { Map introspectedValues = new HashMap<>(); - introspectedValues.put(OAuth2IntrospectionClaimNames.ACTIVE, true); - introspectedValues.put(OAuth2IntrospectionClaimNames.AUDIENCE, Arrays.asList("aud")); - introspectedValues.put(OAuth2IntrospectionClaimNames.NOT_BEFORE, 29348723984L); + introspectedValues.put(OAuth2TokenIntrospectionClaimNames.ACTIVE, true); + introspectedValues.put(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("aud")); + introspectedValues.put(OAuth2TokenIntrospectionClaimNames.NBF, 29348723984L); WebClient webClient = mockResponse(new JSONObject(introspectedValues).toJSONString()); NimbusReactiveOpaqueTokenIntrospector introspectionClient = new NimbusReactiveOpaqueTokenIntrospector( INTROSPECTION_URL, webClient); @@ -161,11 +162,11 @@ public class NimbusReactiveOpaqueTokenIntrospectorTests { // @formatter:off assertThat(authority.getAttributes()) .isNotNull() - .containsEntry(OAuth2IntrospectionClaimNames.ACTIVE, true) - .containsEntry(OAuth2IntrospectionClaimNames.AUDIENCE, Arrays.asList("aud")) - .containsEntry(OAuth2IntrospectionClaimNames.NOT_BEFORE, Instant.ofEpochSecond(29348723984L)) - .doesNotContainKey(OAuth2IntrospectionClaimNames.CLIENT_ID) - .doesNotContainKey(OAuth2IntrospectionClaimNames.SCOPE); + .containsEntry(OAuth2TokenIntrospectionClaimNames.ACTIVE, true) + .containsEntry(OAuth2TokenIntrospectionClaimNames.AUD, Arrays.asList("aud")) + .containsEntry(OAuth2TokenIntrospectionClaimNames.NBF, Instant.ofEpochSecond(29348723984L)) + .doesNotContainKey(OAuth2TokenIntrospectionClaimNames.CLIENT_ID) + .doesNotContainKey(OAuth2TokenIntrospectionClaimNames.SCOPE); // @formatter:on } diff --git a/test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java b/test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java index e489335c6f..c77a889f8f 100644 --- a/test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java +++ b/test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java @@ -56,6 +56,7 @@ import org.springframework.security.oauth2.client.web.server.WebSessionServerOAu import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.OidcUserInfo; @@ -71,7 +72,6 @@ import org.springframework.security.oauth2.server.resource.authentication.Bearer import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.security.web.server.csrf.CsrfWebFilter; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; @@ -648,14 +648,14 @@ public final class SecurityMockServerConfigurers { private Map defaultAttributes() { Map attributes = new HashMap<>(); - attributes.put(OAuth2IntrospectionClaimNames.SUBJECT, "user"); - attributes.put(OAuth2IntrospectionClaimNames.SCOPE, "read"); + attributes.put(OAuth2TokenIntrospectionClaimNames.SUB, "user"); + attributes.put(OAuth2TokenIntrospectionClaimNames.SCOPE, "read"); return attributes; } private Collection defaultAuthorities() { Map attributes = this.attributes.get(); - Object scope = attributes.get(OAuth2IntrospectionClaimNames.SCOPE); + Object scope = attributes.get(OAuth2TokenIntrospectionClaimNames.SCOPE); if (scope == null) { return Collections.emptyList(); } diff --git a/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java b/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java index a1d88b2e09..4d140655f5 100644 --- a/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java +++ b/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -70,6 +70,7 @@ import org.springframework.security.oauth2.client.web.method.annotation.OAuth2Au import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.OidcUserInfo; @@ -85,7 +86,6 @@ import org.springframework.security.oauth2.server.resource.authentication.Bearer import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.test.context.TestSecurityContextHolder; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.security.test.web.support.WebTestUtils; @@ -1191,14 +1191,14 @@ public final class SecurityMockMvcRequestPostProcessors { private Map defaultAttributes() { Map attributes = new HashMap<>(); - attributes.put(OAuth2IntrospectionClaimNames.SUBJECT, "user"); - attributes.put(OAuth2IntrospectionClaimNames.SCOPE, "read"); + attributes.put(OAuth2TokenIntrospectionClaimNames.SUB, "user"); + attributes.put(OAuth2TokenIntrospectionClaimNames.SCOPE, "read"); return attributes; } private Collection defaultAuthorities() { Map attributes = this.attributes.get(); - Object scope = attributes.get(OAuth2IntrospectionClaimNames.SCOPE); + Object scope = attributes.get(OAuth2TokenIntrospectionClaimNames.SCOPE); if (scope == null) { return Collections.emptyList(); } diff --git a/test/src/test/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurerOpaqueTokenTests.java b/test/src/test/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurerOpaqueTokenTests.java index 7c4096fd95..44213e8661 100644 --- a/test/src/test/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurerOpaqueTokenTests.java +++ b/test/src/test/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurerOpaqueTokenTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -29,9 +29,9 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipals; import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; -import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.web.reactive.result.method.annotation.CurrentSecurityContextArgumentResolver; import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter; import org.springframework.test.web.reactive.server.WebTestClient; @@ -64,7 +64,7 @@ public class SecurityMockServerConfigurerOpaqueTokenTests extends AbstractMockSe BearerTokenAuthentication token = (BearerTokenAuthentication) context.getAuthentication(); assertThat(token.getAuthorities()).isNotEmpty(); assertThat(token.getToken()).isNotNull(); - assertThat(token.getTokenAttributes().get(OAuth2IntrospectionClaimNames.SUBJECT)).isEqualTo("user"); + assertThat(token.getTokenAttributes().get(OAuth2TokenIntrospectionClaimNames.SUB)).isEqualTo("user"); } @Test @@ -83,12 +83,12 @@ public class SecurityMockServerConfigurerOpaqueTokenTests extends AbstractMockSe String sub = new String("my-subject"); this.client .mutateWith(SecurityMockServerConfigurers.mockOpaqueToken() - .attributes((attributes) -> attributes.put(OAuth2IntrospectionClaimNames.SUBJECT, sub))) + .attributes((attributes) -> attributes.put(OAuth2TokenIntrospectionClaimNames.SUB, sub))) .get().exchange().expectStatus().isOk(); SecurityContext context = this.securityContextController.removeSecurityContext(); assertThat(context.getAuthentication()).isInstanceOf(BearerTokenAuthentication.class); BearerTokenAuthentication token = (BearerTokenAuthentication) context.getAuthentication(); - assertThat(token.getTokenAttributes().get(OAuth2IntrospectionClaimNames.SUBJECT)).isSameAs(sub); + assertThat(token.getTokenAttributes().get(OAuth2TokenIntrospectionClaimNames.SUB)).isSameAs(sub); } @Test @@ -108,23 +108,23 @@ public class SecurityMockServerConfigurerOpaqueTokenTests extends AbstractMockSe .active((a) -> a.put("scope", "user")); this.client .mutateWith(SecurityMockServerConfigurers.mockOpaqueToken() - .attributes((a) -> a.put(OAuth2IntrospectionClaimNames.SUBJECT, "foo")).principal(principal)) + .attributes((a) -> a.put(OAuth2TokenIntrospectionClaimNames.SUB, "foo")).principal(principal)) .get().exchange().expectStatus().isOk(); SecurityContext context = this.securityContextController.removeSecurityContext(); assertThat(context.getAuthentication()).isInstanceOf(BearerTokenAuthentication.class); BearerTokenAuthentication token = (BearerTokenAuthentication) context.getAuthentication(); assertThat((String) ((OAuth2AuthenticatedPrincipal) token.getPrincipal()) - .getAttribute(OAuth2IntrospectionClaimNames.SUBJECT)) - .isEqualTo(principal.getAttribute(OAuth2IntrospectionClaimNames.SUBJECT)); + .getAttribute(OAuth2TokenIntrospectionClaimNames.SUB)) + .isEqualTo(principal.getAttribute(OAuth2TokenIntrospectionClaimNames.SUB)); this.client .mutateWith(SecurityMockServerConfigurers.mockOpaqueToken().principal(principal) - .attributes((a) -> a.put(OAuth2IntrospectionClaimNames.SUBJECT, "bar"))) + .attributes((a) -> a.put(OAuth2TokenIntrospectionClaimNames.SUB, "bar"))) .get().exchange().expectStatus().isOk(); context = this.securityContextController.removeSecurityContext(); assertThat(context.getAuthentication()).isInstanceOf(BearerTokenAuthentication.class); token = (BearerTokenAuthentication) context.getAuthentication(); assertThat((String) ((OAuth2AuthenticatedPrincipal) token.getPrincipal()) - .getAttribute(OAuth2IntrospectionClaimNames.SUBJECT)).isEqualTo("bar"); + .getAttribute(OAuth2TokenIntrospectionClaimNames.SUB)).isEqualTo("bar"); } }