diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java index 4a41b1e2da..1229ea8881 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java @@ -26,6 +26,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Base64; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -359,7 +360,7 @@ public class OAuth2AuthorizationCodeGrantTests { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); this.registeredClientRepository.save(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); this.authorizationService.save(authorization); OAuth2AccessTokenResponse accessTokenResponse = assertTokenRequestReturnsAccessTokenResponse(registeredClient, @@ -384,7 +385,7 @@ public class OAuth2AuthorizationCodeGrantTests { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); this.registeredClientRepository.save(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); this.authorizationService.save(authorization); assertTokenRequestReturnsAccessTokenResponse(registeredClient, authorization, @@ -433,8 +434,6 @@ public class OAuth2AuthorizationCodeGrantTests { MvcResult mvcResult = this.mvc .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI) .queryParams(getAuthorizationRequestParameters(registeredClient)) - .queryParam(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE) - .queryParam(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256") .with(user("user"))) .andExpect(status().is3xxRedirection()) .andReturn(); @@ -451,8 +450,7 @@ public class OAuth2AuthorizationCodeGrantTests { this.mvc .perform(post(DEFAULT_TOKEN_ENDPOINT_URI) .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) - .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER)) + .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())) .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store"))) .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache"))) .andExpect(status().isOk()) @@ -487,8 +485,6 @@ public class OAuth2AuthorizationCodeGrantTests { MvcResult mvcResult = this.mvc .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI) .queryParams(getAuthorizationRequestParameters(registeredClient)) - .queryParam(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE) - .queryParam(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256") .with(user("user"))) .andExpect(status().is3xxRedirection()) .andReturn(); @@ -505,8 +501,7 @@ public class OAuth2AuthorizationCodeGrantTests { this.mvc .perform(post(DEFAULT_TOKEN_ENDPOINT_URI) .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) - .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER)) + .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())) .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store"))) .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache"))) .andExpect(status().isOk()) @@ -542,11 +537,11 @@ public class OAuth2AuthorizationCodeGrantTests { tokenRequestParameters.set(OAuth2ParameterNames.CODE, ""); tokenRequestParameters.set(OAuth2ParameterNames.REDIRECT_URI, registeredClient.getRedirectUris().iterator().next()); + tokenRequestParameters.set(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER); this.mvc .perform(post(DEFAULT_TOKEN_ENDPOINT_URI).params(tokenRequestParameters) - .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER)) + .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())) .andExpect(status().isBadRequest()); } @@ -561,8 +556,6 @@ public class OAuth2AuthorizationCodeGrantTests { registeredClient); MvcResult mvcResult = this.mvc .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI).queryParams(authorizationRequestParameters) - .queryParam(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE) - .queryParam(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256") .with(user("user"))) .andExpect(status().is3xxRedirection()) .andReturn(); @@ -577,9 +570,12 @@ public class OAuth2AuthorizationCodeGrantTests { assertThat(authorizationCodeAuthorization.getAuthorizationGrantType()) .isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE); + MultiValueMap tokenRequestParameters = getTokenRequestParameters(registeredClient, + authorizationCodeAuthorization); + tokenRequestParameters.remove(PkceParameterNames.CODE_VERIFIER); + this.mvc - .perform(post(DEFAULT_TOKEN_ENDPOINT_URI) - .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) + .perform(post(DEFAULT_TOKEN_ENDPOINT_URI).params(tokenRequestParameters) .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient))) .andExpect(status().isBadRequest()); @@ -595,11 +591,12 @@ public class OAuth2AuthorizationCodeGrantTests { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().redirectUris((redirectUris) -> { redirectUris.clear(); redirectUris.add(redirectUri); - }).clientSettings(ClientSettings.builder().requireProofKey(true).build()).build(); + }).build(); this.registeredClientRepository.save(registeredClient); MultiValueMap authorizationRequestParameters = getAuthorizationRequestParameters( registeredClient); + authorizationRequestParameters.remove(PkceParameterNames.CODE_CHALLENGE); MvcResult mvcResult = this.mvc .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI).queryParams(authorizationRequestParameters) .with(user("user"))) @@ -618,11 +615,14 @@ public class OAuth2AuthorizationCodeGrantTests { throws Exception { this.spring.register(AuthorizationServerConfiguration.class).autowire(); - RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); + RegisteredClient registeredClient = TestRegisteredClients.registeredClient() + .clientSettings(ClientSettings.builder().requireProofKey(false).build()) + .build(); this.registeredClientRepository.save(registeredClient); MultiValueMap authorizationRequestParameters = getAuthorizationRequestParameters( registeredClient); + authorizationRequestParameters.remove(PkceParameterNames.CODE_CHALLENGE); MvcResult mvcResult = this.mvc .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI).queryParams(authorizationRequestParameters) .with(user("user"))) @@ -642,7 +642,6 @@ public class OAuth2AuthorizationCodeGrantTests { this.mvc .perform(post(DEFAULT_TOKEN_ENDPOINT_URI) .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER) .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient))) .andExpect(status().isBadRequest()); } @@ -654,7 +653,7 @@ public class OAuth2AuthorizationCodeGrantTests { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); this.registeredClientRepository.save(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); this.authorizationService.save(authorization); this.mvc @@ -704,10 +703,14 @@ public class OAuth2AuthorizationCodeGrantTests { OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient) .principalName("user") .build(); + Map additionalParameters = new HashMap<>(); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); OAuth2AuthorizationRequest authorizationRequest = authorization .getAttribute(OAuth2AuthorizationRequest.class.getName()); OAuth2AuthorizationRequest updatedAuthorizationRequest = OAuth2AuthorizationRequest.from(authorizationRequest) .state(STATE_URL_UNENCODED) + .additionalParameters(additionalParameters) .build(); authorization = OAuth2Authorization.from(authorization) .attribute(OAuth2AuthorizationRequest.class.getName(), updatedAuthorizationRequest) @@ -793,7 +796,7 @@ public class OAuth2AuthorizationCodeGrantTests { .build(); this.registeredClientRepository.save(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); OAuth2AuthorizationRequest authorizationRequest = authorization .getAttribute(OAuth2AuthorizationRequest.class.getName()); OAuth2AuthorizationRequest updatedAuthorizationRequest = OAuth2AuthorizationRequest.from(authorizationRequest) @@ -906,8 +909,6 @@ public class OAuth2AuthorizationCodeGrantTests { MvcResult mvcResult = this.mvc .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI) .queryParams(getAuthorizationRequestParameters(registeredClient)) - .queryParam(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE) - .queryParam(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256") .with(user("user"))) .andExpect(status().is3xxRedirection()) .andReturn(); @@ -926,8 +927,7 @@ public class OAuth2AuthorizationCodeGrantTests { mvcResult = this.mvc .perform(post(DEFAULT_TOKEN_ENDPOINT_URI) .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) - .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER)) + .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())) .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store"))) .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache"))) .andExpect(status().isOk()) @@ -956,8 +956,6 @@ public class OAuth2AuthorizationCodeGrantTests { MvcResult mvcResult = this.mvc .perform(get(issuer.concat(DEFAULT_AUTHORIZATION_ENDPOINT_URI)) .queryParams(getAuthorizationRequestParameters(registeredClient)) - .queryParam(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE) - .queryParam(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256") .with(user("user"))) .andExpect(status().is3xxRedirection()) .andReturn(); @@ -969,8 +967,7 @@ public class OAuth2AuthorizationCodeGrantTests { this.mvc .perform(post(issuer.concat(DEFAULT_TOKEN_ENDPOINT_URI)) .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) - .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER)) + .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())) .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store"))) .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache"))) .andExpect(status().isOk()) @@ -994,7 +991,7 @@ public class OAuth2AuthorizationCodeGrantTests { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); this.registeredClientRepository.save(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); this.authorizationService.save(authorization); String tokenEndpointUri = "http://localhost" + DEFAULT_TOKEN_ENDPOINT_URI; @@ -1025,8 +1022,6 @@ public class OAuth2AuthorizationCodeGrantTests { MvcResult mvcResult = this.mvc .perform(post("/oauth2/par").params(getAuthorizationRequestParameters(registeredClient)) - .param(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE) - .param(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256") .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient))) .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store"))) .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache"))) @@ -1053,7 +1048,6 @@ public class OAuth2AuthorizationCodeGrantTests { .perform(post(DEFAULT_TOKEN_ENDPOINT_URI) .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) .param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId()) - .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER) .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient))) .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store"))) .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache"))) @@ -1077,6 +1071,13 @@ public class OAuth2AuthorizationCodeGrantTests { .isEqualTo(true); } + private static OAuth2Authorization createAuthorization(RegisteredClient registeredClient) { + Map additionalParameters = new HashMap<>(); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); + return TestOAuth2Authorizations.authorization(registeredClient, additionalParameters).build(); + } + private static String generateDPoPProof(String tokenEndpointUri) { // @formatter:off Map publicJwk = TestJwks.DEFAULT_EC_JWK @@ -1105,6 +1106,8 @@ public class OAuth2AuthorizationCodeGrantTests { parameters.set(OAuth2ParameterNames.SCOPE, StringUtils.collectionToDelimitedString(registeredClient.getScopes(), " ")); parameters.set(OAuth2ParameterNames.STATE, STATE_URL_UNENCODED); + parameters.set(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + parameters.set(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); return parameters; } @@ -1115,6 +1118,7 @@ public class OAuth2AuthorizationCodeGrantTests { parameters.set(OAuth2ParameterNames.CODE, authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()); parameters.set(OAuth2ParameterNames.REDIRECT_URI, registeredClient.getRedirectUris().iterator().next()); + parameters.set(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER); return parameters; } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java index 22fab0395a..c01a8bd3e0 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java @@ -89,6 +89,7 @@ import org.springframework.security.oauth2.server.authorization.client.TestRegis import org.springframework.security.oauth2.server.authorization.http.converter.OAuth2TokenIntrospectionHttpMessageConverter; import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; 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.token.OAuth2TokenClaimsContext; @@ -310,6 +311,7 @@ public class OAuth2TokenIntrospectionTests { .build(); RegisteredClient authorizedRegisteredClient = TestRegisteredClients.registeredClient() .tokenSettings(tokenSettings) + .clientSettings(ClientSettings.builder().requireProofKey(false).build()) .build(); // @formatter:on this.registeredClientRepository.save(authorizedRegisteredClient); diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java index edc0040de9..e9109cec34 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java @@ -22,8 +22,10 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.Principal; import java.util.Base64; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import com.nimbusds.jose.jwk.JWKSet; @@ -69,6 +71,7 @@ import org.springframework.security.oauth2.core.OAuth2Token; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.core.endpoint.PkceParameterNames; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; @@ -133,6 +136,12 @@ public class OidcTests { private static final String DEFAULT_OIDC_LOGOUT_ENDPOINT_URI = "/connect/logout"; + // See RFC 7636: Appendix B. Example for the S256 code_challenge_method + // https://tools.ietf.org/html/rfc7636#appendix-B + private static final String S256_CODE_VERIFIER = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; + + private static final String S256_CODE_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"; + private static final String AUTHORITIES_CLAIM = "authorities"; private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE); @@ -462,7 +471,7 @@ public class OidcTests { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scope(OidcScopes.OPENID).build(); this.registeredClientRepository.save(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); this.authorizationService.save(authorization); this.mvc @@ -557,6 +566,13 @@ public class OidcTests { .andReturn(); } + private static OAuth2Authorization createAuthorization(RegisteredClient registeredClient) { + Map additionalParameters = new HashMap<>(); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); + return TestOAuth2Authorizations.authorization(registeredClient, additionalParameters).build(); + } + private static MultiValueMap getAuthorizationRequestParameters(RegisteredClient registeredClient) { MultiValueMap parameters = new LinkedMultiValueMap<>(); parameters.set(OAuth2ParameterNames.RESPONSE_TYPE, OAuth2AuthorizationResponseType.CODE.getValue()); @@ -565,6 +581,8 @@ public class OidcTests { parameters.set(OAuth2ParameterNames.SCOPE, StringUtils.collectionToDelimitedString(registeredClient.getScopes(), " ")); parameters.set(OAuth2ParameterNames.STATE, "state"); + parameters.set(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + parameters.set(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); return parameters; } @@ -575,6 +593,7 @@ public class OidcTests { parameters.set(OAuth2ParameterNames.CODE, authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue()); parameters.set(OAuth2ParameterNames.REDIRECT_URI, registeredClient.getRedirectUris().iterator().next()); + parameters.set(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER); return parameters; } diff --git a/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettings.java b/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettings.java index 155b3ebfe8..67e1ecbed6 100644 --- a/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettings.java +++ b/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettings.java @@ -44,7 +44,7 @@ public final class ClientSettings extends AbstractSettings { /** * Returns {@code true} if the client is required to provide a proof key challenge and * verifier when performing the Authorization Code Grant flow. The default is - * {@code false}. + * {@code true}. * @return {@code true} if the client is required to provide a proof key challenge and * verifier, {@code false} otherwise */ @@ -99,7 +99,7 @@ public final class ClientSettings extends AbstractSettings { * @return the {@link Builder} */ public static Builder builder() { - return new Builder().requireProofKey(false).requireAuthorizationConsent(false); + return new Builder().requireProofKey(true).requireAuthorizationConsent(false); } /** diff --git a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProviderTests.java b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProviderTests.java index f3352825ab..486bc6dc7e 100644 --- a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProviderTests.java +++ b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProviderTests.java @@ -267,11 +267,12 @@ public class ClientSecretAuthenticationProviderTests { given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); + OAuth2Authorization authorization = createAuthorization(registeredClient); given(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE))) - .willReturn(TestOAuth2Authorizations.authorization().build()); + .willReturn(authorization); OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken( registeredClient.getClientId(), ClientAuthenticationMethod.CLIENT_SECRET_BASIC, - registeredClient.getClientSecret(), createAuthorizationCodeTokenParameters()); + registeredClient.getClientSecret(), createPkceTokenParameters(S256_CODE_VERIFIER)); OAuth2ClientAuthenticationToken authenticationResult = (OAuth2ClientAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -289,9 +290,7 @@ public class ClientSecretAuthenticationProviderTests { given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations - .authorization(registeredClient, createPkceAuthorizationParametersS256()) - .build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); given(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE))) .willReturn(authorization); @@ -317,9 +316,7 @@ public class ClientSecretAuthenticationProviderTests { given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations - .authorization(registeredClient, createPkceAuthorizationParametersS256()) - .build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); given(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE))) .willReturn(authorization); @@ -344,9 +341,7 @@ public class ClientSecretAuthenticationProviderTests { given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); - OAuth2Authorization authorization = TestOAuth2Authorizations - .authorization(registeredClient, createPkceAuthorizationParametersS256()) - .build(); + OAuth2Authorization authorization = createAuthorization(registeredClient); given(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE))) .willReturn(authorization); @@ -366,6 +361,13 @@ public class ClientSecretAuthenticationProviderTests { assertThat(authenticationResult.getRegisteredClient()).isEqualTo(registeredClient); } + private static OAuth2Authorization createAuthorization(RegisteredClient registeredClient) { + Map parameters = new HashMap<>(); + parameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); + parameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + return TestOAuth2Authorizations.authorization(registeredClient, parameters).build(); + } + private static Map createAuthorizationCodeTokenParameters() { Map parameters = new HashMap<>(); parameters.put(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.AUTHORIZATION_CODE.getValue()); @@ -379,11 +381,4 @@ public class ClientSecretAuthenticationProviderTests { return parameters; } - private static Map createPkceAuthorizationParametersS256() { - Map parameters = new HashMap<>(); - parameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); - parameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); - return parameters; - } - } diff --git a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java index 1f04409e47..c1ac268067 100644 --- a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java +++ b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java @@ -75,6 +75,12 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { private static final String AUTHORIZATION_URI = "https://provider.com/oauth2/authorize"; + // See RFC 7636: Appendix B. Example for the S256 code_challenge_method + // https://tools.ietf.org/html/rfc7636#appendix-B + private static final String S256_CODE_VERIFIER = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; + + private static final String S256_CODE_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"; + private static final String STATE = "state"; private static final OAuth2TokenType STATE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.STATE); @@ -225,7 +231,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { .willReturn(registeredClient); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, "https://127.0.0.1:5000", STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -244,7 +250,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { .willReturn(registeredClient); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, "https://[::1]:5000", STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -319,9 +325,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { @Test public void authenticateWhenPkceRequiredAndMissingCodeChallengeThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() { - RegisteredClient registeredClient = TestRegisteredClients.registeredClient() - .clientSettings(ClientSettings.builder().requireProofKey(true).build()) - .build(); + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; @@ -341,7 +345,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { .willReturn(registeredClient); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[0]; Map additionalParameters = new HashMap<>(); - additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, "code-challenge"); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "unsupported"); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, @@ -360,7 +364,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { .willReturn(registeredClient); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; Map additionalParameters = new HashMap<>(); - additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, "code-challenge"); + additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, registeredClient.getScopes(), additionalParameters); @@ -394,7 +398,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put("prompt", prompt); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, @@ -412,7 +416,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { .willReturn(registeredClient); this.principal.setAuthenticated(false); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put("prompt", "none"); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, @@ -433,7 +437,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[1]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -451,7 +455,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { given(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))) .willReturn(registeredClient); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put("prompt", "none"); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, @@ -473,7 +477,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[0]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationConsentAuthenticationToken authenticationResult = (OAuth2AuthorizationConsentAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -524,7 +528,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[1]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -551,7 +555,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -574,7 +578,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[1]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -592,12 +596,9 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { .willReturn(registeredClient); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[0]; - Map additionalParameters = new HashMap<>(); - additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, "code-challenge"); - additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), additionalParameters); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -614,7 +615,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri .create(); - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put(OAuth2ParameterNames.REQUEST_URI, pushedAuthorizationRequestUri.getRequestUri()); OAuth2Authorization authorization = TestOAuth2Authorizations .authorization(registeredClient, additionalParameters) @@ -640,7 +641,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri .create(); - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put(OAuth2ParameterNames.REQUEST_URI, pushedAuthorizationRequestUri.getRequestUri()); OAuth2Authorization authorization = TestOAuth2Authorizations .authorization(registeredClient, additionalParameters) @@ -665,7 +666,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri .create(); - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put(OAuth2ParameterNames.REQUEST_URI, pushedAuthorizationRequestUri.getRequestUri()); OAuth2Authorization authorization = TestOAuth2Authorizations .authorization(registeredClient, additionalParameters) @@ -689,7 +690,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri .create(Instant.now().minusSeconds(5)); - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put(OAuth2ParameterNames.REQUEST_URI, pushedAuthorizationRequestUri.getRequestUri()); OAuth2Authorization authorization = TestOAuth2Authorizations .authorization(registeredClient, additionalParameters) @@ -721,7 +722,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[1]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); assertThatExceptionOfType(OAuth2AuthorizationCodeRequestAuthenticationException.class) .isThrownBy(() -> this.authenticationProvider.authenticate(authentication)) @@ -746,7 +747,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; OAuth2AuthorizationCodeRequestAuthenticationToken authentication = new OAuth2AuthorizationCodeRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); @@ -812,4 +813,11 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { assertThat(authorizationCodeRequestAuthentication.getRedirectUri()).isEqualTo(redirectUri); } + private static Map createPkceParameters() { + Map parameters = new HashMap<>(); + parameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); + parameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + return parameters; + } + } diff --git a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2PushedAuthorizationRequestAuthenticationProviderTests.java b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2PushedAuthorizationRequestAuthenticationProviderTests.java index 81088aebf3..b704062db3 100644 --- a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2PushedAuthorizationRequestAuthenticationProviderTests.java +++ b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2PushedAuthorizationRequestAuthenticationProviderTests.java @@ -40,7 +40,6 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; -import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -57,6 +56,12 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { private static final String AUTHORIZATION_URI = "https://provider.com/oauth2/par"; + // See RFC 7636: Appendix B. Example for the S256 code_challenge_method + // https://tools.ietf.org/html/rfc7636#appendix-B + private static final String S256_CODE_VERIFIER = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; + + private static final String S256_CODE_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"; + private static final String STATE = "state"; private OAuth2AuthorizationService authorizationService; @@ -177,7 +182,7 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); OAuth2PushedAuthorizationRequestAuthenticationToken authentication = new OAuth2PushedAuthorizationRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), clientPrincipal, "https://127.0.0.1:5000", STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2PushedAuthorizationRequestAuthenticationToken authenticationResult = (OAuth2PushedAuthorizationRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); assertPushedAuthorizationResponse(registeredClient, authentication, authenticationResult); @@ -192,7 +197,7 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); OAuth2PushedAuthorizationRequestAuthenticationToken authentication = new OAuth2PushedAuthorizationRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), clientPrincipal, "https://[::1]:5000", STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2PushedAuthorizationRequestAuthenticationToken authenticationResult = (OAuth2PushedAuthorizationRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); assertPushedAuthorizationResponse(registeredClient, authentication, authenticationResult); @@ -246,9 +251,7 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { @Test public void authenticateWhenPkceRequiredAndMissingCodeChallengeThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() { - RegisteredClient registeredClient = TestRegisteredClients.registeredClient() - .clientSettings(ClientSettings.builder().requireProofKey(true).build()) - .build(); + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; @@ -320,7 +323,7 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; - Map additionalParameters = new HashMap<>(); + Map additionalParameters = createPkceParameters(); additionalParameters.put("prompt", prompt); OAuth2PushedAuthorizationRequestAuthenticationToken authentication = new OAuth2PushedAuthorizationRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), clientPrincipal, redirectUri, STATE, @@ -337,12 +340,9 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret()); String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[0]; - Map additionalParameters = new HashMap<>(); - additionalParameters.put(PkceParameterNames.CODE_CHALLENGE, "code-challenge"); - additionalParameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); OAuth2PushedAuthorizationRequestAuthenticationToken authentication = new OAuth2PushedAuthorizationRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), clientPrincipal, redirectUri, STATE, - registeredClient.getScopes(), additionalParameters); + registeredClient.getScopes(), createPkceParameters()); OAuth2PushedAuthorizationRequestAuthenticationToken authenticationResult = (OAuth2PushedAuthorizationRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); assertPushedAuthorizationResponse(registeredClient, authentication, authenticationResult); @@ -360,7 +360,7 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { String redirectUri = registeredClient.getRedirectUris().toArray(new String[0])[2]; OAuth2PushedAuthorizationRequestAuthenticationToken authentication = new OAuth2PushedAuthorizationRequestAuthenticationToken( AUTHORIZATION_URI, registeredClient.getClientId(), clientPrincipal, redirectUri, STATE, - registeredClient.getScopes(), null); + registeredClient.getScopes(), createPkceParameters()); OAuth2PushedAuthorizationRequestAuthenticationToken authenticationResult = (OAuth2PushedAuthorizationRequestAuthenticationToken) this.authenticationProvider .authenticate(authentication); assertPushedAuthorizationResponse(registeredClient, authentication, authenticationResult); @@ -415,4 +415,11 @@ public class OAuth2PushedAuthorizationRequestAuthenticationProviderTests { assertThat(authorizationCodeRequestAuthentication.getRedirectUri()).isEqualTo(redirectUri); } + private static Map createPkceParameters() { + Map parameters = new HashMap<>(); + parameters.put(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"); + parameters.put(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE); + return parameters; + } + } diff --git a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettingsTests.java b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettingsTests.java index 4d5ec88d6f..fe0caa8775 100644 --- a/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettingsTests.java +++ b/oauth2/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/settings/ClientSettingsTests.java @@ -33,7 +33,7 @@ public class ClientSettingsTests { public void buildWhenDefaultThenDefaultsAreSet() { ClientSettings clientSettings = ClientSettings.builder().build(); assertThat(clientSettings.getSettings()).hasSize(2); - assertThat(clientSettings.isRequireProofKey()).isFalse(); + assertThat(clientSettings.isRequireProofKey()).isTrue(); assertThat(clientSettings.isRequireAuthorizationConsent()).isFalse(); }