Skip to content

Commit a2c694d

Browse files
committed
PKCE configuration - enabled by default
Signed-off-by: Rohan Naik <[email protected]>
1 parent 7a7d2ca commit a2c694d

File tree

7 files changed

+45
-11
lines changed

7 files changed

+45
-11
lines changed

docs/modules/ROOT/pages/servlet/oauth2/client/client-authentication.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,6 @@ spring:
293293

294294
[NOTE]
295295
====
296-
Public Clients are supported using https://tools.ietf.org/html/rfc7636[Proof Key for Code Exchange] (PKCE).
297-
PKCE will automatically be used when `client-authentication-method` is set to "none" (`ClientAuthenticationMethod.NONE`).
296+
https://tools.ietf.org/html/rfc7636[Proof Key for Code Exchange] (PKCE) will be enabled by default for public as well as confidential clients. Refer https://docs.spring.io/spring-security/reference/servlet/oauth2/client/client-authentication.html#oauth2-client-authentication-public[this
297+
section] to disable PKCE.
298298
====

docs/modules/ROOT/pages/servlet/oauth2/client/core.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ This information is available only if the Spring Boot property `spring.security.
6969
<15> `(userInfoEndpoint)authenticationMethod`: The authentication method used when sending the access token to the UserInfo Endpoint.
7070
The supported values are *header*, *form*, and *query*.
7171
<16> `userNameAttributeName`: The name of the attribute returned in the UserInfo Response that references the Name or Identifier of the end-user.
72-
<17> [[oauth2Client-client-registration-requireProofKey]]`requireProofKey`: If `true` or if `authorizationGrantType` is `none`, then PKCE will be enabled by default.
72+
<17> [[oauth2Client-client-registration-requireProofKey]]`requireProofKey`: This will by default be `true`, as PKCE will be enabled by default.
73+
If set to `false`,then PKCE will be disabled for public as well as confidential clients.
7374

7475
You can initially configure a `ClientRegistration` by using discovery of an OpenID Connect Provider's https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Configuration endpoint] or an Authorization Server's https://tools.ietf.org/html/rfc8414#section-3[Metadata endpoint].
7576

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ public static final class ClientSettings implements Serializable {
757757
private boolean requireProofKey;
758758

759759
private ClientSettings() {
760-
760+
this.requireProofKey = true;
761761
}
762762

763763
public boolean isRequireProofKey() {

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolver.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,7 @@ private OAuth2AuthorizationRequest.Builder getBuilder(ClientRegistration clientR
184184
// value.
185185
applyNonce(builder);
186186
}
187-
if (ClientAuthenticationMethod.NONE.equals(clientRegistration.getClientAuthenticationMethod())
188-
|| clientRegistration.getClientSettings().isRequireProofKey()) {
187+
if (clientRegistration.getClientSettings().isRequireProofKey()) {
189188
DEFAULT_PKCE_APPLIER.accept(builder);
190189
}
191190
return builder;

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolver.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -196,8 +196,7 @@ private OAuth2AuthorizationRequest.Builder getBuilder(ClientRegistration clientR
196196
// value.
197197
applyNonce(builder);
198198
}
199-
if (ClientAuthenticationMethod.NONE.equals(clientRegistration.getClientAuthenticationMethod())
200-
|| clientRegistration.getClientSettings().isRequireProofKey()) {
199+
if (clientRegistration.getClientSettings().isRequireProofKey()) {
201200
DEFAULT_PKCE_APPLIER.accept(builder);
202201
}
203202
return builder;

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/TestClientRegistrations.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -64,6 +64,21 @@ public static ClientRegistration.Builder clientRegistration2() {
6464
// @formatter:on
6565
}
6666

67+
private static ClientRegistration.Builder publicClientRegistrationWithNoPkce() {
68+
return ClientRegistration.withRegistrationId("no-pkce")
69+
.redirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}")
70+
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
71+
.clientSettings(ClientRegistration.ClientSettings.builder().requireProofKey(false).build())
72+
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
73+
.scope("read:user")
74+
.authorizationUri("https://example.com/login/oauth/authorize")
75+
.tokenUri("https://example.com/login/oauth/access_token")
76+
.userInfoUri("https://api.example.com/user")
77+
.userNameAttributeName("id")
78+
.clientName("Client Name")
79+
.clientSecret(null);
80+
}
81+
6782
public static ClientRegistration.Builder clientCredentials() {
6883
// @formatter:off
6984
return clientRegistration()

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolverTests.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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;
@@ -427,6 +429,25 @@ public void resolveWhenAuthorizationRequestApplyPkceToConfidentialClientsThenApp
427429
assertPkceApplied(authorizationRequest, clientRegistration);
428430
}
429431

432+
@Test
433+
public void resolveWhenAuthorizationRequestApplyPkceToConfidentialClientThenApplied() {
434+
// pkce enabled by default for private clients
435+
ClientRegistration clientRegistration = this.registration1;
436+
String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
437+
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
438+
OAuth2AuthorizationRequest authorizationRequest = this.resolver.resolve(request);
439+
assertPkceApplied(authorizationRequest, clientRegistration);
440+
}
441+
442+
@Test
443+
public void resolveWhenAuthorizationRequestApplyPkceToPublicClientWithRequireProofKeyFalseThenApplied() {
444+
ClientRegistration clientRegistration = this.nonProofKeyPublicClientRegistration; // change to non proof key public client
445+
String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
446+
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
447+
OAuth2AuthorizationRequest authorizationRequest = this.resolver.resolve(request);
448+
assertPkceNotApplied(authorizationRequest, clientRegistration);
449+
}
450+
430451
// gh-6548
431452
@Test
432453
public void resolveWhenAuthorizationRequestApplyPkceToSpecificConfidentialClientThenApplied() {
@@ -593,7 +614,6 @@ private static ClientRegistration.Builder pkceClientRegistration() {
593614
.clientId("client-id-3")
594615
.clientSecret("client-secret");
595616
}
596-
597617
private static ClientRegistration.Builder fineRedirectUriTemplateClientRegistration() {
598618
// @formatter:off
599619
return ClientRegistration.withRegistrationId("fine-redirect-uri-template-client-registration")

0 commit comments

Comments
 (0)