Skip to content

Commit 48115fa

Browse files
aijazkeeriojgrandja
authored andcommitted
Fix empty code parameter in CodeVerifierAuthenticator
Closes spring-projectsgh-1680
1 parent 72d7fb1 commit 48115fa

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/CodeVerifierAuthenticator.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,16 @@ private boolean authenticate(OAuth2ClientAuthenticationToken clientAuthenticatio
137137
}
138138

139139
private static boolean authorizationCodeGrant(Map<String, Object> parameters) {
140-
// @formatter:off
141-
return AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(
142-
parameters.get(OAuth2ParameterNames.GRANT_TYPE)) &&
143-
parameters.get(OAuth2ParameterNames.CODE) != null;
144-
// @formatter:on
140+
141+
if (!AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(parameters.get(OAuth2ParameterNames.GRANT_TYPE))) {
142+
return false;
143+
}
144+
145+
if (!StringUtils.hasText((String) parameters.get(OAuth2ParameterNames.CODE))) {
146+
throwInvalidGrant(OAuth2ParameterNames.CODE);
147+
}
148+
149+
return true;
145150
}
146151

147152
private boolean codeVerifierValid(String codeVerifier, String codeChallenge, String codeChallengeMethod) {

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProviderTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import static org.mockito.BDDMockito.given;
4747
import static org.mockito.Mockito.mock;
4848
import static org.mockito.Mockito.spy;
49+
import static org.mockito.Mockito.times;
4950
import static org.mockito.Mockito.verify;
5051

5152
/**

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.time.temporal.ChronoUnit;
2626
import java.util.Arrays;
2727
import java.util.Base64;
28+
import java.util.Collections;
2829
import java.util.HashSet;
2930
import java.util.List;
3031
import java.util.Map;
@@ -71,6 +72,7 @@
7172
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
7273
import org.springframework.security.crypto.password.PasswordEncoder;
7374
import org.springframework.security.oauth2.core.AuthorizationGrantType;
75+
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
7476
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
7577
import org.springframework.security.oauth2.core.OAuth2Token;
7678
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
@@ -98,6 +100,7 @@
98100
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationContext;
99101
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationProvider;
100102
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken;
103+
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
101104
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
102105
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
103106
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -515,6 +518,28 @@ public void requestWhenPublicClientWithPkceAndCustomRefreshTokenGeneratorThenRet
515518
.isEqualTo(true);
516519
}
517520

521+
@Test
522+
public void requestWhenPublicClientWithPkceAndEmptyCodeThenBadRequest() throws Exception {
523+
this.spring.register(AuthorizationServerConfiguration.class).autowire();
524+
525+
RegisteredClient registeredClient = TestRegisteredClients.registeredPublicClient().build();
526+
this.registeredClientRepository.save(registeredClient);
527+
528+
MultiValueMap<String, String> tokenRequestParameters = new LinkedMultiValueMap<>();
529+
tokenRequestParameters.set(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.AUTHORIZATION_CODE.getValue());
530+
tokenRequestParameters.set(OAuth2ParameterNames.CODE, "");
531+
tokenRequestParameters.set(OAuth2ParameterNames.REDIRECT_URI, registeredClient.getRedirectUris().iterator().next());
532+
533+
this.mvc
534+
.perform(post(DEFAULT_TOKEN_ENDPOINT_URI)
535+
.params(tokenRequestParameters)
536+
.param(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())
537+
.param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER))
538+
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store")))
539+
.andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache")))
540+
.andExpect(status().isBadRequest());
541+
}
542+
518543
@Test
519544
public void requestWhenConfidentialClientWithPkceAndMissingCodeVerifierThenBadRequest() throws Exception {
520545
this.spring.register(AuthorizationServerConfiguration.class).autowire();

0 commit comments

Comments
 (0)