2626import  java .time .temporal .ChronoUnit ;
2727import  java .util .Arrays ;
2828import  java .util .Base64 ;
29+ import  java .util .HashMap ;
2930import  java .util .HashSet ;
3031import  java .util .List ;
3132import  java .util .Map ;
@@ -359,7 +360,7 @@ public void requestWhenTokenRequestValidThenReturnAccessTokenResponse() throws E
359360		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ().build ();
360361		this .registeredClientRepository .save (registeredClient );
361362
362- 		OAuth2Authorization  authorization  = TestOAuth2Authorizations . authorization (registeredClient ). build ( );
363+ 		OAuth2Authorization  authorization  = createAuthorization (registeredClient );
363364		this .authorizationService .save (authorization );
364365
365366		OAuth2AccessTokenResponse  accessTokenResponse  = assertTokenRequestReturnsAccessTokenResponse (registeredClient ,
@@ -384,7 +385,7 @@ public void requestWhenTokenRequestCustomEndpointThenReturnAccessTokenResponse()
384385		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ().build ();
385386		this .registeredClientRepository .save (registeredClient );
386387
387- 		OAuth2Authorization  authorization  = TestOAuth2Authorizations . authorization (registeredClient ). build ( );
388+ 		OAuth2Authorization  authorization  = createAuthorization (registeredClient );
388389		this .authorizationService .save (authorization );
389390
390391		assertTokenRequestReturnsAccessTokenResponse (registeredClient , authorization ,
@@ -433,8 +434,6 @@ public void requestWhenPublicClientWithPkceThenReturnAccessTokenResponse() throw
433434		MvcResult  mvcResult  = this .mvc 
434435			.perform (get (DEFAULT_AUTHORIZATION_ENDPOINT_URI )
435436				.queryParams (getAuthorizationRequestParameters (registeredClient ))
436- 				.queryParam (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE )
437- 				.queryParam (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" )
438437				.with (user ("user" )))
439438			.andExpect (status ().is3xxRedirection ())
440439			.andReturn ();
@@ -451,8 +450,7 @@ public void requestWhenPublicClientWithPkceThenReturnAccessTokenResponse() throw
451450		this .mvc 
452451			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI )
453452				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
454- 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
455- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER ))
453+ 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ()))
456454			.andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
457455			.andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
458456			.andExpect (status ().isOk ())
@@ -487,8 +485,6 @@ public void requestWhenPublicClientWithPkceAndCustomRefreshTokenGeneratorThenRet
487485		MvcResult  mvcResult  = this .mvc 
488486			.perform (get (DEFAULT_AUTHORIZATION_ENDPOINT_URI )
489487				.queryParams (getAuthorizationRequestParameters (registeredClient ))
490- 				.queryParam (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE )
491- 				.queryParam (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" )
492488				.with (user ("user" )))
493489			.andExpect (status ().is3xxRedirection ())
494490			.andReturn ();
@@ -505,8 +501,7 @@ public void requestWhenPublicClientWithPkceAndCustomRefreshTokenGeneratorThenRet
505501		this .mvc 
506502			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI )
507503				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
508- 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
509- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER ))
504+ 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ()))
510505			.andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
511506			.andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
512507			.andExpect (status ().isOk ())
@@ -542,11 +537,11 @@ public void requestWhenPublicClientWithPkceAndEmptyCodeThenBadRequest() throws E
542537		tokenRequestParameters .set (OAuth2ParameterNames .CODE , "" );
543538		tokenRequestParameters .set (OAuth2ParameterNames .REDIRECT_URI ,
544539				registeredClient .getRedirectUris ().iterator ().next ());
540+ 		tokenRequestParameters .set (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER );
545541
546542		this .mvc 
547543			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI ).params (tokenRequestParameters )
548- 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
549- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER ))
544+ 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ()))
550545			.andExpect (status ().isBadRequest ());
551546	}
552547
@@ -561,8 +556,6 @@ public void requestWhenConfidentialClientWithPkceAndMissingCodeVerifierThenBadRe
561556				registeredClient );
562557		MvcResult  mvcResult  = this .mvc 
563558			.perform (get (DEFAULT_AUTHORIZATION_ENDPOINT_URI ).queryParams (authorizationRequestParameters )
564- 				.queryParam (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE )
565- 				.queryParam (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" )
566559				.with (user ("user" )))
567560			.andExpect (status ().is3xxRedirection ())
568561			.andReturn ();
@@ -577,9 +570,12 @@ public void requestWhenConfidentialClientWithPkceAndMissingCodeVerifierThenBadRe
577570		assertThat (authorizationCodeAuthorization .getAuthorizationGrantType ())
578571			.isEqualTo (AuthorizationGrantType .AUTHORIZATION_CODE );
579572
573+ 		MultiValueMap <String , String > tokenRequestParameters  = getTokenRequestParameters (registeredClient ,
574+ 				authorizationCodeAuthorization );
575+ 		tokenRequestParameters .remove (PkceParameterNames .CODE_VERIFIER );
576+ 
580577		this .mvc 
581- 			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI )
582- 				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
578+ 			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI ).params (tokenRequestParameters )
583579				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
584580				.header (HttpHeaders .AUTHORIZATION , getAuthorizationHeader (registeredClient )))
585581			.andExpect (status ().isBadRequest ());
@@ -595,11 +591,12 @@ public void requestWhenConfidentialClientWithPkceAndMissingCodeChallengeThenErro
595591		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ().redirectUris ((redirectUris ) -> {
596592			redirectUris .clear ();
597593			redirectUris .add (redirectUri );
598- 		}).clientSettings ( ClientSettings . builder (). requireProofKey ( true ). build ()). build ();
594+ 		}).build ();
599595		this .registeredClientRepository .save (registeredClient );
600596
601597		MultiValueMap <String , String > authorizationRequestParameters  = getAuthorizationRequestParameters (
602598				registeredClient );
599+ 		authorizationRequestParameters .remove (PkceParameterNames .CODE_CHALLENGE );
603600		MvcResult  mvcResult  = this .mvc 
604601			.perform (get (DEFAULT_AUTHORIZATION_ENDPOINT_URI ).queryParams (authorizationRequestParameters )
605602				.with (user ("user" )))
@@ -618,11 +615,14 @@ public void requestWhenConfidentialClientWithPkceAndMissingCodeChallengeButCodeV
618615			throws  Exception  {
619616		this .spring .register (AuthorizationServerConfiguration .class ).autowire ();
620617
621- 		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ().build ();
618+ 		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ()
619+ 			.clientSettings (ClientSettings .builder ().requireProofKey (false ).build ())
620+ 			.build ();
622621		this .registeredClientRepository .save (registeredClient );
623622
624623		MultiValueMap <String , String > authorizationRequestParameters  = getAuthorizationRequestParameters (
625624				registeredClient );
625+ 		authorizationRequestParameters .remove (PkceParameterNames .CODE_CHALLENGE );
626626		MvcResult  mvcResult  = this .mvc 
627627			.perform (get (DEFAULT_AUTHORIZATION_ENDPOINT_URI ).queryParams (authorizationRequestParameters )
628628				.with (user ("user" )))
@@ -642,7 +642,6 @@ public void requestWhenConfidentialClientWithPkceAndMissingCodeChallengeButCodeV
642642		this .mvc 
643643			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI )
644644				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
645- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER )
646645				.header (HttpHeaders .AUTHORIZATION , getAuthorizationHeader (registeredClient )))
647646			.andExpect (status ().isBadRequest ());
648647	}
@@ -654,7 +653,7 @@ public void requestWhenCustomTokenGeneratorThenUsed() throws Exception {
654653		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ().build ();
655654		this .registeredClientRepository .save (registeredClient );
656655
657- 		OAuth2Authorization  authorization  = TestOAuth2Authorizations . authorization (registeredClient ). build ( );
656+ 		OAuth2Authorization  authorization  = createAuthorization (registeredClient );
658657		this .authorizationService .save (authorization );
659658
660659		this .mvc 
@@ -704,10 +703,14 @@ public void requestWhenConsentRequestThenReturnAccessTokenResponse() throws Exce
704703		OAuth2Authorization  authorization  = TestOAuth2Authorizations .authorization (registeredClient )
705704			.principalName ("user" )
706705			.build ();
706+ 		Map <String , Object > additionalParameters  = new  HashMap <>();
707+ 		additionalParameters .put (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE );
708+ 		additionalParameters .put (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" );
707709		OAuth2AuthorizationRequest  authorizationRequest  = authorization 
708710			.getAttribute (OAuth2AuthorizationRequest .class .getName ());
709711		OAuth2AuthorizationRequest  updatedAuthorizationRequest  = OAuth2AuthorizationRequest .from (authorizationRequest )
710712			.state (STATE_URL_UNENCODED )
713+ 			.additionalParameters (additionalParameters )
711714			.build ();
712715		authorization  = OAuth2Authorization .from (authorization )
713716			.attribute (OAuth2AuthorizationRequest .class .getName (), updatedAuthorizationRequest )
@@ -793,7 +796,7 @@ public void requestWhenCustomConsentCustomizerConfiguredThenUsed() throws Except
793796			.build ();
794797		this .registeredClientRepository .save (registeredClient );
795798
796- 		OAuth2Authorization  authorization  = TestOAuth2Authorizations . authorization (registeredClient ). build ( );
799+ 		OAuth2Authorization  authorization  = createAuthorization (registeredClient );
797800		OAuth2AuthorizationRequest  authorizationRequest  = authorization 
798801			.getAttribute (OAuth2AuthorizationRequest .class .getName ());
799802		OAuth2AuthorizationRequest  updatedAuthorizationRequest  = OAuth2AuthorizationRequest .from (authorizationRequest )
@@ -906,8 +909,6 @@ public void requestWhenClientObtainsAccessTokenThenClientAuthenticationNotPersis
906909		MvcResult  mvcResult  = this .mvc 
907910			.perform (get (DEFAULT_AUTHORIZATION_ENDPOINT_URI )
908911				.queryParams (getAuthorizationRequestParameters (registeredClient ))
909- 				.queryParam (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE )
910- 				.queryParam (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" )
911912				.with (user ("user" )))
912913			.andExpect (status ().is3xxRedirection ())
913914			.andReturn ();
@@ -926,8 +927,7 @@ public void requestWhenClientObtainsAccessTokenThenClientAuthenticationNotPersis
926927		mvcResult  = this .mvc 
927928			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI )
928929				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
929- 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
930- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER ))
930+ 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ()))
931931			.andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
932932			.andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
933933			.andExpect (status ().isOk ())
@@ -956,8 +956,6 @@ public void requestWhenAuthorizationAndTokenRequestIncludesIssuerPathThenIssuerR
956956		MvcResult  mvcResult  = this .mvc 
957957			.perform (get (issuer .concat (DEFAULT_AUTHORIZATION_ENDPOINT_URI ))
958958				.queryParams (getAuthorizationRequestParameters (registeredClient ))
959- 				.queryParam (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE )
960- 				.queryParam (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" )
961959				.with (user ("user" )))
962960			.andExpect (status ().is3xxRedirection ())
963961			.andReturn ();
@@ -969,8 +967,7 @@ public void requestWhenAuthorizationAndTokenRequestIncludesIssuerPathThenIssuerR
969967		this .mvc 
970968			.perform (post (issuer .concat (DEFAULT_TOKEN_ENDPOINT_URI ))
971969				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
972- 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
973- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER ))
970+ 				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ()))
974971			.andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
975972			.andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
976973			.andExpect (status ().isOk ())
@@ -994,7 +991,7 @@ public void requestWhenTokenRequestWithDPoPProofThenReturnDPoPBoundAccessToken()
994991		RegisteredClient  registeredClient  = TestRegisteredClients .registeredClient ().build ();
995992		this .registeredClientRepository .save (registeredClient );
996993
997- 		OAuth2Authorization  authorization  = TestOAuth2Authorizations . authorization (registeredClient ). build ( );
994+ 		OAuth2Authorization  authorization  = createAuthorization (registeredClient );
998995		this .authorizationService .save (authorization );
999996
1000997		String  tokenEndpointUri  = "http://localhost"  + DEFAULT_TOKEN_ENDPOINT_URI ;
@@ -1025,8 +1022,6 @@ public void requestWhenPushedAuthorizationRequestThenReturnAccessTokenResponse()
10251022
10261023		MvcResult  mvcResult  = this .mvc 
10271024			.perform (post ("/oauth2/par" ).params (getAuthorizationRequestParameters (registeredClient ))
1028- 				.param (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE )
1029- 				.param (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" )
10301025				.header (HttpHeaders .AUTHORIZATION , getAuthorizationHeader (registeredClient )))
10311026			.andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
10321027			.andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
@@ -1053,7 +1048,6 @@ public void requestWhenPushedAuthorizationRequestThenReturnAccessTokenResponse()
10531048			.perform (post (DEFAULT_TOKEN_ENDPOINT_URI )
10541049				.params (getTokenRequestParameters (registeredClient , authorizationCodeAuthorization ))
10551050				.param (OAuth2ParameterNames .CLIENT_ID , registeredClient .getClientId ())
1056- 				.param (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER )
10571051				.header (HttpHeaders .AUTHORIZATION , getAuthorizationHeader (registeredClient )))
10581052			.andExpect (header ().string (HttpHeaders .CACHE_CONTROL , containsString ("no-store" )))
10591053			.andExpect (header ().string (HttpHeaders .PRAGMA , containsString ("no-cache" )))
@@ -1077,6 +1071,13 @@ public void requestWhenPushedAuthorizationRequestThenReturnAccessTokenResponse()
10771071			.isEqualTo (true );
10781072	}
10791073
1074+ 	private  static  OAuth2Authorization  createAuthorization (RegisteredClient  registeredClient ) {
1075+ 		Map <String , Object > additionalParameters  = new  HashMap <>();
1076+ 		additionalParameters .put (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE );
1077+ 		additionalParameters .put (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" );
1078+ 		return  TestOAuth2Authorizations .authorization (registeredClient , additionalParameters ).build ();
1079+ 	}
1080+ 
10801081	private  static  String  generateDPoPProof (String  tokenEndpointUri ) {
10811082		// @formatter:off 
10821083		Map <String , Object > publicJwk  = TestJwks .DEFAULT_EC_JWK 
@@ -1105,6 +1106,8 @@ private static MultiValueMap<String, String> getAuthorizationRequestParameters(R
11051106		parameters .set (OAuth2ParameterNames .SCOPE ,
11061107				StringUtils .collectionToDelimitedString (registeredClient .getScopes (), " " ));
11071108		parameters .set (OAuth2ParameterNames .STATE , STATE_URL_UNENCODED );
1109+ 		parameters .set (PkceParameterNames .CODE_CHALLENGE , S256_CODE_CHALLENGE );
1110+ 		parameters .set (PkceParameterNames .CODE_CHALLENGE_METHOD , "S256" );
11081111		return  parameters ;
11091112	}
11101113
@@ -1115,6 +1118,7 @@ private static MultiValueMap<String, String> getTokenRequestParameters(Registere
11151118		parameters .set (OAuth2ParameterNames .CODE ,
11161119				authorization .getToken (OAuth2AuthorizationCode .class ).getToken ().getTokenValue ());
11171120		parameters .set (OAuth2ParameterNames .REDIRECT_URI , registeredClient .getRedirectUris ().iterator ().next ());
1121+ 		parameters .set (PkceParameterNames .CODE_VERIFIER , S256_CODE_VERIFIER );
11181122		return  parameters ;
11191123	}
11201124
0 commit comments