From 64b20ae3eb053bd7be44ceb7167d2c695b13d4f9 Mon Sep 17 00:00:00 2001 From: Joe Grandja <10884212+jgrandja@users.noreply.github.com> Date: Tue, 14 May 2024 12:33:24 -0400 Subject: [PATCH] Fix package tangle Closes gh-1615 --- .../DefaultOAuth2TokenCustomizers.java} | 33 ++- .../configurers/OAuth2ConfigurerUtils.java | 30 ++- .../authorization/token/JwtGenerator.java | 3 +- .../token/OAuth2AccessTokenGenerator.java | 3 +- .../DefaultOAuth2TokenCustomizersTests.java | 239 ++++++++++++++++++ ...DefaultOAuth2TokenClaimsConsumerTests.java | 128 ---------- .../token/JwtGeneratorTests.java | 34 +-- .../OAuth2AccessTokenGeneratorTests.java | 18 +- 8 files changed, 286 insertions(+), 202 deletions(-) rename oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/{token/DefaultOAuth2TokenClaimsConsumer.java => config/annotation/web/configurers/DefaultOAuth2TokenCustomizers.java} (74%) create mode 100644 oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/DefaultOAuth2TokenCustomizersTests.java delete mode 100644 oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumerTests.java diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/DefaultOAuth2TokenCustomizers.java similarity index 74% rename from oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumer.java rename to oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/DefaultOAuth2TokenCustomizers.java index 704b1022..d970c092 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumer.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/DefaultOAuth2TokenCustomizers.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.oauth2.server.authorization.token; +package org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers; import java.security.MessageDigest; import java.security.cert.X509Certificate; @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import java.util.function.Consumer; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; @@ -32,28 +31,36 @@ import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeActor; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeCompositeAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimNames; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; /** * @author Joe Grandja + * @author Steve Riesenberg * @since 1.3 */ -final class DefaultOAuth2TokenClaimsConsumer implements Consumer> { - private final OAuth2TokenContext context; +final class DefaultOAuth2TokenCustomizers { - DefaultOAuth2TokenClaimsConsumer(OAuth2TokenContext context) { - this.context = context; + static OAuth2TokenCustomizer jwtCustomizer() { + return (context) -> context.getClaims().claims((claims) -> customize(context, claims)); } - @Override - public void accept(Map claims) { + static OAuth2TokenCustomizer accessTokenCustomizer() { + return (context) -> context.getClaims().claims((claims) -> customize(context, claims)); + } + + private static void customize(OAuth2TokenContext tokenContext, Map claims) { // Add 'cnf' claim for Mutual-TLS Client Certificate-Bound Access Tokens - if (OAuth2TokenType.ACCESS_TOKEN.equals(this.context.getTokenType()) && - this.context.getAuthorizationGrant() != null && - this.context.getAuthorizationGrant().getPrincipal() instanceof OAuth2ClientAuthenticationToken clientAuthentication) { + if (OAuth2TokenType.ACCESS_TOKEN.equals(tokenContext.getTokenType()) && + tokenContext.getAuthorizationGrant() != null && + tokenContext.getAuthorizationGrant().getPrincipal() instanceof OAuth2ClientAuthenticationToken clientAuthentication) { if ((ClientAuthenticationMethod.TLS_CLIENT_AUTH.equals(clientAuthentication.getClientAuthenticationMethod()) || ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH.equals(clientAuthentication.getClientAuthenticationMethod())) && - this.context.getRegisteredClient().getTokenSettings().isX509CertificateBoundAccessTokens()) { + tokenContext.getRegisteredClient().getTokenSettings().isX509CertificateBoundAccessTokens()) { X509Certificate[] clientCertificateChain = (X509Certificate[]) clientAuthentication.getCredentials(); try { @@ -71,7 +78,7 @@ final class DefaultOAuth2TokenClaimsConsumer implements Consumer currentClaims = claims; for (OAuth2TokenExchangeActor actor : compositeAuthenticationToken.getActors()) { Map actorClaims = actor.getClaims(); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java index 5238b655..fee9a586 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java @@ -105,10 +105,7 @@ final class OAuth2ConfigurerUtils { if (tokenGenerator == null) { JwtGenerator jwtGenerator = getJwtGenerator(httpSecurity); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); - OAuth2TokenCustomizer accessTokenCustomizer = getAccessTokenCustomizer(httpSecurity); - if (accessTokenCustomizer != null) { - accessTokenGenerator.setAccessTokenCustomizer(accessTokenCustomizer); - } + accessTokenGenerator.setAccessTokenCustomizer(getAccessTokenCustomizer(httpSecurity)); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); if (jwtGenerator != null) { tokenGenerator = new DelegatingOAuth2TokenGenerator( @@ -129,10 +126,7 @@ final class OAuth2ConfigurerUtils { JwtEncoder jwtEncoder = getJwtEncoder(httpSecurity); if (jwtEncoder != null) { jwtGenerator = new JwtGenerator(jwtEncoder); - OAuth2TokenCustomizer jwtCustomizer = getJwtCustomizer(httpSecurity); - if (jwtCustomizer != null) { - jwtGenerator.setJwtCustomizer(jwtCustomizer); - } + jwtGenerator.setJwtCustomizer(getJwtCustomizer(httpSecurity)); httpSecurity.setSharedObject(JwtGenerator.class, jwtGenerator); } } @@ -170,13 +164,29 @@ final class OAuth2ConfigurerUtils { } private static OAuth2TokenCustomizer getJwtCustomizer(HttpSecurity httpSecurity) { + final OAuth2TokenCustomizer defaultJwtCustomizer = DefaultOAuth2TokenCustomizers.jwtCustomizer(); ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2TokenCustomizer.class, JwtEncodingContext.class); - return getOptionalBean(httpSecurity, type); + final OAuth2TokenCustomizer jwtCustomizer = getOptionalBean(httpSecurity, type); + if (jwtCustomizer == null) { + return defaultJwtCustomizer; + } + return (context) -> { + defaultJwtCustomizer.customize(context); + jwtCustomizer.customize(context); + }; } private static OAuth2TokenCustomizer getAccessTokenCustomizer(HttpSecurity httpSecurity) { + final OAuth2TokenCustomizer defaultAccessTokenCustomizer = DefaultOAuth2TokenCustomizers.accessTokenCustomizer(); ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2TokenCustomizer.class, OAuth2TokenClaimsContext.class); - return getOptionalBean(httpSecurity, type); + OAuth2TokenCustomizer accessTokenCustomizer = getOptionalBean(httpSecurity, type); + if (accessTokenCustomizer == null) { + return defaultAccessTokenCustomizer; + } + return (context) -> { + defaultAccessTokenCustomizer.customize(context); + accessTokenCustomizer.customize(context); + }; } static AuthorizationServerSettings getAuthorizationServerSettings(HttpSecurity httpSecurity) { diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java index b57573b7..84247b54 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 the original author or authors. + * Copyright 2020-2023 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. @@ -144,7 +144,6 @@ public final class JwtGenerator implements OAuth2TokenGenerator { } } } - claimsBuilder.claims(new DefaultOAuth2TokenClaimsConsumer(context)); // @formatter:on JwsHeader.Builder jwsHeaderBuilder = JwsHeader.with(jwsAlgorithm); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGenerator.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGenerator.java index e3a9d1ee..4e203335 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGenerator.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 the original author or authors. + * Copyright 2020-2022 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. @@ -84,7 +84,6 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator actClaim1 = (Map) jwtClaimsSet.getClaims().get("act"); + assertThat(actClaim1.get(JwtClaimNames.ISS)).isEqualTo(ISSUER_1); + assertThat(actClaim1.get(JwtClaimNames.SUB)).isEqualTo("actor1"); + @SuppressWarnings("unchecked") + Map actClaim2 = (Map) actClaim1.get("act"); + assertThat(actClaim2.get(JwtClaimNames.ISS)).isEqualTo(ISSUER_2); + assertThat(actClaim2.get(JwtClaimNames.SUB)).isEqualTo("actor2"); + } + + @Test + void customizeWhenPKIX509ClientCertificateAndCertificateBoundAccessTokensThenX5tClaimAdded() { + // @formatter:off + RegisteredClient registeredClient = TestRegisteredClients.registeredClient() + .clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH) + .clientSettings( + ClientSettings.builder() + .x509CertificateSubjectDN(TestX509Certificates.DEMO_CLIENT_PKI_CERTIFICATE[0].getSubjectX500Principal().getName()) + .build() + ) + .tokenSettings( + TokenSettings.builder() + .x509CertificateBoundAccessTokens(true) + .build() + ) + .build(); + // @formatter:on + OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( + registeredClient, ClientAuthenticationMethod.TLS_CLIENT_AUTH, + TestX509Certificates.DEMO_CLIENT_PKI_CERTIFICATE); + OAuth2ClientCredentialsAuthenticationToken clientCredentialsAuthentication = + new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, null, null); + // @formatter:off + JwtEncodingContext tokenContext = JwtEncodingContext.with(this.jwsHeaderBuilder, this.jwtClaimsBuilder) + .tokenType(OAuth2TokenType.ACCESS_TOKEN) + .registeredClient(registeredClient) + .authorizationGrant(clientCredentialsAuthentication) + .build(); + // @formatter:on + DefaultOAuth2TokenCustomizers.jwtCustomizer().customize(tokenContext); + JwtClaimsSet jwtClaimsSet = this.jwtClaimsBuilder.build(); + assertThat(jwtClaimsSet.getClaims()).isNotEmpty(); + assertThat(jwtClaimsSet.getClaims()).hasSize(2); + Map cnfClaim = jwtClaimsSet.getClaim("cnf"); + assertThat(cnfClaim).isNotEmpty(); + assertThat(cnfClaim.get("x5t#S256")).isNotNull(); + } + + @Test + void customizeWhenSelfSignedX509ClientCertificateAndCertificateBoundAccessTokensThenX5tClaimAdded() { + // @formatter:off + RegisteredClient registeredClient = TestRegisteredClients.registeredClient() + .clientAuthenticationMethod(ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH) + .clientSettings( + ClientSettings.builder() + .jwkSetUrl("https://client.example.com/jwks") + .build() + ) + .tokenSettings( + TokenSettings.builder() + .x509CertificateBoundAccessTokens(true) + .build() + ) + .build(); + // @formatter:on + OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( + registeredClient, ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH, + TestX509Certificates.DEMO_CLIENT_SELF_SIGNED_CERTIFICATE); + OAuth2ClientCredentialsAuthenticationToken clientCredentialsAuthentication = + new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, null, null); + // @formatter:off + JwtEncodingContext tokenContext = JwtEncodingContext.with(this.jwsHeaderBuilder, this.jwtClaimsBuilder) + .tokenType(OAuth2TokenType.ACCESS_TOKEN) + .registeredClient(registeredClient) + .authorizationGrant(clientCredentialsAuthentication) + .build(); + // @formatter:on + DefaultOAuth2TokenCustomizers.jwtCustomizer().customize(tokenContext); + JwtClaimsSet jwtClaimsSet = this.jwtClaimsBuilder.build(); + assertThat(jwtClaimsSet.getClaims()).isNotEmpty(); + assertThat(jwtClaimsSet.getClaims()).hasSize(2); + Map cnfClaim = jwtClaimsSet.getClaim("cnf"); + assertThat(cnfClaim).isNotEmpty(); + assertThat(cnfClaim.get("x5t#S256")).isNotNull(); + } + +} diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumerTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumerTests.java deleted file mode 100644 index 5458b69a..00000000 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/DefaultOAuth2TokenClaimsConsumerTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2020-2024 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 java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeActor; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeAuthenticationToken; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeCompositeAuthenticationToken; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link DefaultOAuth2TokenClaimsConsumer}. - * - * @author Steve Riesenberg - */ -public class DefaultOAuth2TokenClaimsConsumerTests { - - private OAuth2TokenContext tokenContext; - - private Consumer> consumer; - - @BeforeEach - public void setUp() { - this.tokenContext = mock(OAuth2TokenContext.class); - this.consumer = new DefaultOAuth2TokenClaimsConsumer(this.tokenContext); - } - - @Test - public void acceptWhenTokenTypeIsRefreshTokenThenNoClaimsAdded() { - when(this.tokenContext.getTokenType()).thenReturn(OAuth2TokenType.REFRESH_TOKEN); - Map claims = new LinkedHashMap<>(); - this.consumer.accept(claims); - assertThat(claims).isEmpty(); - } - - @Test - public void acceptWhenAuthorizationGrantIsNullThenNoClaimsAdded() { - when(this.tokenContext.getTokenType()).thenReturn(OAuth2TokenType.ACCESS_TOKEN); - when(this.tokenContext.getAuthorizationGrant()).thenReturn(null); - Map claims = new LinkedHashMap<>(); - this.consumer.accept(claims); - assertThat(claims).isEmpty(); - } - - @Test - public void acceptWhenTokenExchangeGrantAndResourcesThenNoClaimsAdded() { - OAuth2TokenExchangeAuthenticationToken tokenExchangeAuthentication = mock( - OAuth2TokenExchangeAuthenticationToken.class); - when(tokenExchangeAuthentication.getResources()).thenReturn(Set.of("resource1", "resource2")); - when(this.tokenContext.getTokenType()).thenReturn(OAuth2TokenType.ACCESS_TOKEN); - when(this.tokenContext.getAuthorizationGrant()).thenReturn(tokenExchangeAuthentication); - Map claims = new LinkedHashMap<>(); - this.consumer.accept(claims); - // We do not populate claims (e.g. `aud`) based on the resource parameter - assertThat(claims).isEmpty(); - } - - @Test - public void acceptWhenTokenExchangeGrantAndAudiencesThenNoClaimsAdded() { - OAuth2TokenExchangeAuthenticationToken tokenExchangeAuthentication = mock( - OAuth2TokenExchangeAuthenticationToken.class); - when(tokenExchangeAuthentication.getAudiences()).thenReturn(Set.of("audience1", "audience2")); - when(this.tokenContext.getTokenType()).thenReturn(OAuth2TokenType.ACCESS_TOKEN); - when(this.tokenContext.getAuthorizationGrant()).thenReturn(tokenExchangeAuthentication); - Map claims = new LinkedHashMap<>(); - this.consumer.accept(claims); - // NOTE: We do not populate claims (e.g. `aud`) based on the audience parameter - assertThat(claims).isEmpty(); - } - - @Test - public void acceptWhenTokenExchangeGrantAndDelegationThenActClaimAdded() { - OAuth2TokenExchangeAuthenticationToken tokenExchangeAuthentication = mock( - OAuth2TokenExchangeAuthenticationToken.class); - when(tokenExchangeAuthentication.getAudiences()).thenReturn(Collections.emptySet()); - when(this.tokenContext.getTokenType()).thenReturn(OAuth2TokenType.ACCESS_TOKEN); - when(this.tokenContext.getAuthorizationGrant()).thenReturn(tokenExchangeAuthentication); - Authentication subject = new TestingAuthenticationToken("subject", null); - OAuth2TokenExchangeActor actor1 = new OAuth2TokenExchangeActor(Map.of(OAuth2TokenClaimNames.ISS, "issuer1", - OAuth2TokenClaimNames.SUB, "actor1")); - OAuth2TokenExchangeActor actor2 = new OAuth2TokenExchangeActor(Map.of(OAuth2TokenClaimNames.ISS, "issuer2", - OAuth2TokenClaimNames.SUB, "actor2")); - OAuth2TokenExchangeCompositeAuthenticationToken principal = new OAuth2TokenExchangeCompositeAuthenticationToken( - subject, List.of(actor1, actor2)); - when(this.tokenContext.getPrincipal()).thenReturn(principal); - Map claims = new LinkedHashMap<>(); - this.consumer.accept(claims); - assertThat(claims).hasSize(1); - assertThat(claims.get("act")).isNotNull(); - @SuppressWarnings("unchecked") - Map actClaim1 = (Map) claims.get("act"); - assertThat(actClaim1.get(OAuth2TokenClaimNames.ISS)).isEqualTo("issuer1"); - assertThat(actClaim1.get(OAuth2TokenClaimNames.SUB)).isEqualTo("actor1"); - @SuppressWarnings("unchecked") - Map actClaim2 = (Map) actClaim1.get("act"); - assertThat(actClaim2.get(OAuth2TokenClaimNames.ISS)).isEqualTo("issuer2"); - assertThat(actClaim2.get(OAuth2TokenClaimNames.SUB)).isEqualTo("actor2"); - } - -} diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java index a941ea5a..07deda57 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 the original author or authors. + * Copyright 2020-2023 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. @@ -53,10 +53,8 @@ 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.context.TestAuthorizationServerContext; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; -import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat; import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; -import org.springframework.security.oauth2.server.authorization.util.TestX509Certificates; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -130,26 +128,11 @@ public class JwtGeneratorTests { @Test public void generateWhenAccessTokenTypeThenReturnJwt() { - // @formatter:off - RegisteredClient registeredClient = TestRegisteredClients.registeredClient() - .clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH) - .clientSettings( - ClientSettings.builder() - .x509CertificateSubjectDN(TestX509Certificates.DEMO_CLIENT_PKI_CERTIFICATE[0].getSubjectX500Principal().getName()) - .build() - ) - .tokenSettings( - TokenSettings.builder() - .x509CertificateBoundAccessTokens(true) - .build() - ) - .build(); - // @formatter:on + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( - registeredClient, ClientAuthenticationMethod.TLS_CLIENT_AUTH, - TestX509Certificates.DEMO_CLIENT_PKI_CERTIFICATE); + registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( OAuth2AuthorizationRequest.class.getName()); OAuth2AuthorizationCodeAuthenticationToken authentication = @@ -342,17 +325,6 @@ public class JwtGeneratorTests { Set scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE); assertThat(scopes).isEqualTo(tokenContext.getAuthorizedScopes()); - - OAuth2ClientAuthenticationToken clientAuthentication = (OAuth2ClientAuthenticationToken) tokenContext.getAuthorizationGrant().getPrincipal(); - if (ClientAuthenticationMethod.TLS_CLIENT_AUTH.equals(clientAuthentication.getClientAuthenticationMethod()) && - tokenContext.getRegisteredClient().getTokenSettings().isX509CertificateBoundAccessTokens()) { - Map cnf = jwtClaimsSet.getClaim("cnf"); - assertThat(cnf).isNotEmpty(); - assertThat(cnf.get("x5t#S256")).isNotNull(); - } else { - Map cnf = jwtClaimsSet.getClaim("cnf"); - assertThat(cnf).isEmpty(); - } } else { assertThat(jwtClaimsSet.getClaim(IdTokenClaimNames.AZP)).isEqualTo(tokenContext.getRegisteredClient().getClientId()); if (tokenContext.getAuthorizationGrantType().equals(AuthorizationGrantType.AUTHORIZATION_CODE)) { diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGeneratorTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGeneratorTests.java index 00ea098a..9b23496f 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGeneratorTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 the original author or authors. + * Copyright 2020-2022 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. @@ -18,7 +18,6 @@ package org.springframework.security.oauth2.server.authorization.token; import java.security.Principal; import java.time.Instant; import java.util.Collections; -import java.util.Map; import java.util.Set; import org.junit.jupiter.api.BeforeEach; @@ -42,10 +41,8 @@ import org.springframework.security.oauth2.server.authorization.client.TestRegis import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContext; import org.springframework.security.oauth2.server.authorization.context.TestAuthorizationServerContext; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; -import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat; import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; -import org.springframework.security.oauth2.server.authorization.util.TestX509Certificates; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -117,16 +114,10 @@ public class OAuth2AccessTokenGeneratorTests { @Test public void generateWhenReferenceAccessTokenTypeThenReturnAccessToken() { // @formatter:off - ClientSettings clientSettings = ClientSettings.builder() - .x509CertificateSubjectDN(TestX509Certificates.DEMO_CLIENT_PKI_CERTIFICATE[0].getSubjectX500Principal().getName()) - .build(); TokenSettings tokenSettings = TokenSettings.builder() .accessTokenFormat(OAuth2TokenFormat.REFERENCE) - .x509CertificateBoundAccessTokens(true) .build(); RegisteredClient registeredClient = TestRegisteredClients.registeredClient() - .clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH) - .clientSettings(clientSettings) .tokenSettings(tokenSettings) .build(); // @formatter:on @@ -134,8 +125,7 @@ public class OAuth2AccessTokenGeneratorTests { Authentication principal = authorization.getAttribute(Principal.class.getName()); OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( - registeredClient, ClientAuthenticationMethod.TLS_CLIENT_AUTH, - TestX509Certificates.DEMO_CLIENT_PKI_CERTIFICATE); + registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( OAuth2AuthorizationRequest.class.getName()); OAuth2AuthorizationCodeAuthenticationToken authentication = @@ -179,10 +169,6 @@ public class OAuth2AccessTokenGeneratorTests { Set scopes = accessTokenClaims.getClaim(OAuth2ParameterNames.SCOPE); assertThat(scopes).isEqualTo(tokenContext.getAuthorizedScopes()); - Map cnf = accessTokenClaims.getClaim("cnf"); - assertThat(cnf).isNotEmpty(); - assertThat(cnf.get("x5t#S256")).isNotNull(); - ArgumentCaptor tokenClaimsContextCaptor = ArgumentCaptor.forClass(OAuth2TokenClaimsContext.class); verify(this.accessTokenCustomizer).customize(tokenClaimsContextCaptor.capture());