@@ -58,6 +58,8 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
58
58
59
59
private ClientRegistration pkceClientRegistration ;
60
60
61
+ private ClientRegistration nonProofKeyPublicClientRegistration ;
62
+
61
63
private ClientRegistration fineRedirectUriTemplateRegistration ;
62
64
63
65
private ClientRegistration publicClientRegistration ;
@@ -76,7 +78,11 @@ public void setUp() {
76
78
this .registration2 = TestClientRegistrations .clientRegistration2 ().build ();
77
79
78
80
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 ();
80
86
this .fineRedirectUriTemplateRegistration = fineRedirectUriTemplateClientRegistration ().build ();
81
87
// @formatter:off
82
88
this .publicClientRegistration = TestClientRegistrations .clientRegistration ()
@@ -92,7 +98,7 @@ public void setUp() {
92
98
// @formatter:on
93
99
this .clientRegistrationRepository = new InMemoryClientRegistrationRepository (this .registration1 ,
94
100
this .registration2 , this .pkceClientRegistration , this .fineRedirectUriTemplateRegistration ,
95
- this .publicClientRegistration , this .oidcRegistration );
101
+ this .publicClientRegistration , this .oidcRegistration , this . nonProofKeyPublicClientRegistration );
96
102
this .resolver = new DefaultOAuth2AuthorizationRequestResolver (this .clientRegistrationRepository ,
97
103
this .authorizationRequestBaseUri );
98
104
}
@@ -173,12 +179,14 @@ public void resolveWhenAuthorizationRequestWithValidClientThenResolves() {
173
179
assertThat (authorizationRequest .getState ()).isNotNull ();
174
180
assertThat (authorizationRequest .getAdditionalParameters ())
175
181
.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 )));
178
186
assertThat (authorizationRequest .getAuthorizationRequestUri ())
179
187
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
180
188
+ "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 " );
182
190
}
183
191
184
192
@ Test
@@ -190,8 +198,10 @@ public void resolveWhenClientAuthorizationRequiredExceptionAvailableThenResolves
190
198
OAuth2AuthorizationRequest authorizationRequest = this .resolver .resolve (request ,
191
199
clientRegistration .getRegistrationId ());
192
200
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 )));
195
205
}
196
206
197
207
@ Test
@@ -299,7 +309,8 @@ public void resolveWhenAuthorizationRequestIncludesPort80ThenExpandedRedirectUri
299
309
assertThat (authorizationRequest .getAuthorizationRequestUri ())
300
310
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
301
311
+ "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" );
303
314
}
304
315
305
316
@ Test
@@ -315,7 +326,8 @@ public void resolveWhenAuthorizationRequestIncludesPort443ThenExpandedRedirectUr
315
326
assertThat (authorizationRequest .getAuthorizationRequestUri ())
316
327
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
317
328
+ "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" );
319
331
}
320
332
321
333
@ Test
@@ -329,7 +341,7 @@ public void resolveWhenClientAuthorizationRequiredExceptionAvailableThenRedirect
329
341
assertThat (authorizationRequest .getAuthorizationRequestUri ())
330
342
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
331
343
+ "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 " );
333
345
}
334
346
335
347
@ Test
@@ -342,7 +354,8 @@ public void resolveWhenAuthorizationRequestOAuth2LoginThenRedirectUriIsLogin() {
342
354
assertThat (authorizationRequest .getAuthorizationRequestUri ())
343
355
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id-2&"
344
356
+ "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" );
346
359
}
347
360
348
361
@ Test
@@ -356,7 +369,8 @@ public void resolveWhenAuthorizationRequestHasActionParameterAuthorizeThenRedire
356
369
assertThat (authorizationRequest .getAuthorizationRequestUri ())
357
370
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
358
371
+ "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" );
360
374
}
361
375
362
376
@ Test
@@ -370,7 +384,7 @@ public void resolveWhenAuthorizationRequestHasActionParameterLoginThenRedirectUr
370
384
assertThat (authorizationRequest .getAuthorizationRequestUri ())
371
385
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id-2&"
372
386
+ "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 " );
374
388
}
375
389
376
390
@ Test
@@ -427,33 +441,32 @@ public void resolveWhenAuthorizationRequestApplyPkceToConfidentialClientsThenApp
427
441
assertPkceApplied (authorizationRequest , clientRegistration );
428
442
}
429
443
430
- // gh-6548
431
444
@ 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
442
447
ClientRegistration clientRegistration = this .registration1 ;
443
448
String requestUri = this .authorizationRequestBaseUri + "/" + clientRegistration .getRegistrationId ();
444
449
MockHttpServletRequest request = new MockHttpServletRequest ("GET" , requestUri );
445
- request .setServletPath (requestUri );
446
450
OAuth2AuthorizationRequest authorizationRequest = this .resolver .resolve (request );
447
451
assertPkceApplied (authorizationRequest , clientRegistration );
452
+ }
448
453
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 );
455
467
}
456
468
469
+ // gh-6548
457
470
private void assertPkceApplied (OAuth2AuthorizationRequest authorizationRequest ,
458
471
ClientRegistration clientRegistration ) {
459
472
assertThat (authorizationRequest .getAdditionalParameters ()).containsKey (PkceParameterNames .CODE_CHALLENGE );
@@ -510,7 +523,7 @@ public void resolveWhenAuthenticationRequestWithValidOidcClientThenResolves() {
510
523
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
511
524
+ "scope=openid&state=.{15,}&"
512
525
+ "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 " );
514
527
}
515
528
516
529
// gh-7696
@@ -530,7 +543,8 @@ public void resolveWhenAuthorizationRequestCustomizerRemovesNonceThenQueryExclud
530
543
assertThat (authorizationRequest .getAuthorizationRequestUri ())
531
544
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
532
545
+ "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" );
534
548
}
535
549
536
550
@ Test
@@ -548,7 +562,8 @@ public void resolveWhenAuthorizationRequestCustomizerAddsParameterThenQueryInclu
548
562
.matches ("https://example.com/login/oauth/authorize\\ ?" + "response_type=code&client_id=client-id&"
549
563
+ "scope=openid&state=.{15,}&"
550
564
+ "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" );
552
567
}
553
568
554
569
@ Test
@@ -565,7 +580,8 @@ public void resolveWhenAuthorizationRequestCustomizerOverridesParameterThenQuery
565
580
assertThat (authorizationRequest .getAuthorizationRequestUri ()).matches (
566
581
"https://example.com/login/oauth/authorize\\ ?" + "response_type=code&" + "scope=openid&state=.{15,}&"
567
582
+ "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" );
569
585
}
570
586
571
587
@ Test
0 commit comments