@@ -58,6 +58,8 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
5858
5959 private ClientRegistration pkceClientRegistration ;
6060
61+ private ClientRegistration nonProofKeyPublicClientRegistration ;
62+
6163 private ClientRegistration fineRedirectUriTemplateRegistration ;
6264
6365 private ClientRegistration publicClientRegistration ;
@@ -76,7 +78,11 @@ public void setUp() {
7678 this .registration2 = TestClientRegistrations .clientRegistration2 ().build ();
7779
7880 this .pkceClientRegistration = pkceClientRegistration ().build ();
79-
81+ this .nonProofKeyPublicClientRegistration = TestClientRegistrations .clientRegistration ()
82+ .registrationId ("invalid-public-client-registration-id" )
83+ .clientAuthenticationMethod (ClientAuthenticationMethod .NONE )
84+ .clientSettings (ClientRegistration .ClientSettings .builder ().requireProofKey (false ).build ())
85+ .build ();
8086 this .fineRedirectUriTemplateRegistration = fineRedirectUriTemplateClientRegistration ().build ();
8187 // @formatter:off
8288 this .publicClientRegistration = TestClientRegistrations .clientRegistration ()
@@ -92,7 +98,7 @@ public void setUp() {
9298 // @formatter:on
9399 this .clientRegistrationRepository = new InMemoryClientRegistrationRepository (this .registration1 ,
94100 this .registration2 , this .pkceClientRegistration , this .fineRedirectUriTemplateRegistration ,
95- this .publicClientRegistration , this .oidcRegistration );
101+ this .publicClientRegistration , this .oidcRegistration , this . nonProofKeyPublicClientRegistration );
96102 this .resolver = new DefaultOAuth2AuthorizationRequestResolver (this .clientRegistrationRepository ,
97103 this .authorizationRequestBaseUri );
98104 }
@@ -173,12 +179,14 @@ public void resolveWhenAuthorizationRequestWithValidClientThenResolves() {
173179 assertThat (authorizationRequest .getState ()).isNotNull ();
174180 assertThat (authorizationRequest .getAdditionalParameters ())
175181 .doesNotContainKey (OAuth2ParameterNames .REGISTRATION_ID );
176- assertThat (authorizationRequest .getAttributes ())
177- .containsExactly (entry (OAuth2ParameterNames .REGISTRATION_ID , clientRegistration .getRegistrationId ()));
182+ assertThat (authorizationRequest .getAttributes ()).containsExactly (
183+ entry (OAuth2ParameterNames .REGISTRATION_ID , clientRegistration .getRegistrationId ()),
184+ entry (PkceParameterNames .CODE_VERIFIER ,
185+ authorizationRequest .getAttributes ().get (PkceParameterNames .CODE_VERIFIER )));
178186 assertThat (authorizationRequest .getAuthorizationRequestUri ())
179187 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
180188 + "scope=read:user&state=.{15,}&"
181- + "redirect_uri=http://localhost/login/oauth2/code/registration-id" );
189+ + "redirect_uri=http://localhost/login/oauth2/code/registration-id&code_challenge=([a-zA-Z0-9 \\ - \\ . \\ _ \\ ~]){43}&code_challenge_method=S256 " );
182190 }
183191
184192 @ Test
@@ -190,8 +198,10 @@ public void resolveWhenClientAuthorizationRequiredExceptionAvailableThenResolves
190198 OAuth2AuthorizationRequest authorizationRequest = this .resolver .resolve (request ,
191199 clientRegistration .getRegistrationId ());
192200 assertThat (authorizationRequest ).isNotNull ();
193- assertThat (authorizationRequest .getAttributes ())
194- .containsExactly (entry (OAuth2ParameterNames .REGISTRATION_ID , clientRegistration .getRegistrationId ()));
201+ assertThat (authorizationRequest .getAttributes ()).containsExactly (
202+ entry (OAuth2ParameterNames .REGISTRATION_ID , clientRegistration .getRegistrationId ()),
203+ entry (PkceParameterNames .CODE_VERIFIER ,
204+ authorizationRequest .getAttributes ().get (PkceParameterNames .CODE_VERIFIER )));
195205 }
196206
197207 @ Test
@@ -299,7 +309,8 @@ public void resolveWhenAuthorizationRequestIncludesPort80ThenExpandedRedirectUri
299309 assertThat (authorizationRequest .getAuthorizationRequestUri ())
300310 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
301311 + "scope=read:user&state=.{15,}&"
302- + "redirect_uri=http://localhost/login/oauth2/code/registration-id" );
312+ + "redirect_uri=http://localhost/login/oauth2/code/registration-id"
313+ + "&code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256" );
303314 }
304315
305316 @ Test
@@ -315,7 +326,8 @@ public void resolveWhenAuthorizationRequestIncludesPort443ThenExpandedRedirectUr
315326 assertThat (authorizationRequest .getAuthorizationRequestUri ())
316327 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
317328 + "scope=read:user&state=.{15,}&"
318- + "redirect_uri=https://example.com/login/oauth2/code/registration-id" );
329+ + "redirect_uri=https://example.com/login/oauth2/code/registration-id"
330+ + "&code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256" );
319331 }
320332
321333 @ Test
@@ -329,7 +341,7 @@ public void resolveWhenClientAuthorizationRequiredExceptionAvailableThenRedirect
329341 assertThat (authorizationRequest .getAuthorizationRequestUri ())
330342 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
331343 + "scope=read:user&state=.{15,}&"
332- + "redirect_uri=http://localhost/authorize/oauth2/code/registration-id" );
344+ + "redirect_uri=http://localhost/authorize/oauth2/code/registration-id&code_challenge=([a-zA-Z0-9 \\ - \\ . \\ _ \\ ~]){43}&code_challenge_method=S256 " );
333345 }
334346
335347 @ Test
@@ -342,7 +354,8 @@ public void resolveWhenAuthorizationRequestOAuth2LoginThenRedirectUriIsLogin() {
342354 assertThat (authorizationRequest .getAuthorizationRequestUri ())
343355 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id-2&"
344356 + "scope=read:user&state=.{15,}&"
345- + "redirect_uri=http://localhost/login/oauth2/code/registration-id-2" );
357+ + "redirect_uri=http://localhost/login/oauth2/code/registration-id-2"
358+ + "&code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256" );
346359 }
347360
348361 @ Test
@@ -356,7 +369,8 @@ public void resolveWhenAuthorizationRequestHasActionParameterAuthorizeThenRedire
356369 assertThat (authorizationRequest .getAuthorizationRequestUri ())
357370 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
358371 + "scope=read:user&state=.{15,}&"
359- + "redirect_uri=http://localhost/authorize/oauth2/code/registration-id" );
372+ + "redirect_uri=http://localhost/authorize/oauth2/code/registration-id&"
373+ + "code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256" );
360374 }
361375
362376 @ Test
@@ -370,7 +384,7 @@ public void resolveWhenAuthorizationRequestHasActionParameterLoginThenRedirectUr
370384 assertThat (authorizationRequest .getAuthorizationRequestUri ())
371385 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id-2&"
372386 + "scope=read:user&state=.{15,}&"
373- + "redirect_uri=http://localhost/login/oauth2/code/registration-id-2" );
387+ + "redirect_uri=http://localhost/login/oauth2/code/registration-id-2&code_challenge=([a-zA-Z0-9 \\ - \\ . \\ _ \\ ~]){43}&code_challenge_method=S256 " );
374388 }
375389
376390 @ Test
@@ -427,33 +441,32 @@ public void resolveWhenAuthorizationRequestApplyPkceToConfidentialClientsThenApp
427441 assertPkceApplied (authorizationRequest , clientRegistration );
428442 }
429443
430- // gh-6548
431444 @ Test
432- public void resolveWhenAuthorizationRequestApplyPkceToSpecificConfidentialClientThenApplied () {
433- this .resolver .setAuthorizationRequestCustomizer ((builder ) -> {
434- builder .attributes ((attrs ) -> {
435- String registrationId = (String ) attrs .get (OAuth2ParameterNames .REGISTRATION_ID );
436- if (this .registration1 .getRegistrationId ().equals (registrationId )) {
437- OAuth2AuthorizationRequestCustomizers .withPkce ().accept (builder );
438- }
439- });
440- });
441-
445+ public void resolveWhenAuthorizationRequestApplyPkceToConfidentialClientThenApplied () {
446+ // pkce enabled by default for private clients
442447 ClientRegistration clientRegistration = this .registration1 ;
443448 String requestUri = this .authorizationRequestBaseUri + "/" + clientRegistration .getRegistrationId ();
444449 MockHttpServletRequest request = new MockHttpServletRequest ("GET" , requestUri );
445- request .setServletPath (requestUri );
446450 OAuth2AuthorizationRequest authorizationRequest = this .resolver .resolve (request );
447451 assertPkceApplied (authorizationRequest , clientRegistration );
452+ }
448453
449- clientRegistration = this .registration2 ;
450- requestUri = this .authorizationRequestBaseUri + "/" + clientRegistration .getRegistrationId ();
451- request = new MockHttpServletRequest ("GET" , requestUri );
452- request .setServletPath (requestUri );
453- authorizationRequest = this .resolver .resolve (request );
454- assertPkceNotApplied (authorizationRequest , clientRegistration );
454+ @ Test
455+ public void resolveWhenAuthorizationRequestApplyPkceToPublicClientWithRequireProofKeyFalseThenApplied () {
456+ ClientRegistration clientRegistration = this .nonProofKeyPublicClientRegistration ; // change
457+ // to
458+ // non
459+ // proof
460+ // key
461+ // public
462+ // client
463+ String requestUri = this .authorizationRequestBaseUri + "/" + clientRegistration .getRegistrationId ();
464+ MockHttpServletRequest request = new MockHttpServletRequest ("GET" , requestUri );
465+ OAuth2AuthorizationRequest authorizationRequest = this .resolver .resolve (request );
466+ assertPkceApplied (authorizationRequest , clientRegistration );
455467 }
456468
469+ // gh-6548
457470 private void assertPkceApplied (OAuth2AuthorizationRequest authorizationRequest ,
458471 ClientRegistration clientRegistration ) {
459472 assertThat (authorizationRequest .getAdditionalParameters ()).containsKey (PkceParameterNames .CODE_CHALLENGE );
@@ -510,7 +523,7 @@ public void resolveWhenAuthenticationRequestWithValidOidcClientThenResolves() {
510523 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
511524 + "scope=openid&state=.{15,}&"
512525 + "redirect_uri=http://localhost/login/oauth2/code/oidc-registration-id&"
513- + "nonce=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}" );
526+ + "nonce=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge=([a-zA-Z0-9 \\ - \\ . \\ _ \\ ~]){43}&code_challenge_method=S256 " );
514527 }
515528
516529 // gh-7696
@@ -530,7 +543,8 @@ public void resolveWhenAuthorizationRequestCustomizerRemovesNonceThenQueryExclud
530543 assertThat (authorizationRequest .getAuthorizationRequestUri ())
531544 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
532545 + "scope=openid&state=.{15,}&"
533- + "redirect_uri=http://localhost/login/oauth2/code/oidc-registration-id" );
546+ + "redirect_uri=http://localhost/login/oauth2/code/oidc-registration-id&"
547+ + "code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256" );
534548 }
535549
536550 @ Test
@@ -548,7 +562,8 @@ public void resolveWhenAuthorizationRequestCustomizerAddsParameterThenQueryInclu
548562 .matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
549563 + "scope=openid&state=.{15,}&"
550564 + "redirect_uri=http://localhost/login/oauth2/code/oidc-registration-id&"
551- + "nonce=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&" + "param1=value1" );
565+ + "nonce=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}"
566+ + "&code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256¶m1=value1" );
552567 }
553568
554569 @ Test
@@ -565,7 +580,8 @@ public void resolveWhenAuthorizationRequestCustomizerOverridesParameterThenQuery
565580 assertThat (authorizationRequest .getAuthorizationRequestUri ()).matches (
566581 "https://example.com/login/oauth/authorize\\ ?" + "response_type=code&" + "scope=openid&state=.{15,}&"
567582 + "redirect_uri=http://localhost/login/oauth2/code/oidc-registration-id&"
568- + "nonce=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&" + "appid=client-id" );
583+ + "nonce=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}"
584+ + "&code_challenge=([a-zA-Z0-9\\ -\\ .\\ _\\ ~]){43}&code_challenge_method=S256&appid=client-id" );
569585 }
570586
571587 @ Test
0 commit comments