Skip to content

Commit e1b6a7b

Browse files
author
Steve Riesenberg
committed
Revert "URL encode client credentials"
This reverts commit c020051. Issue gh-9610 gh-9863 Closes gh-10018
1 parent 8bb69c4 commit e1b6a7b

7 files changed

+23
-177
lines changed

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/OAuth2AuthorizationGrantRequestEntityUtils.java

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -15,18 +15,15 @@
1515
*/
1616
package org.springframework.security.oauth2.client.endpoint;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Collections;
22-
2318
import org.springframework.core.convert.converter.Converter;
2419
import org.springframework.http.HttpHeaders;
2520
import org.springframework.http.MediaType;
2621
import org.springframework.http.RequestEntity;
2722
import org.springframework.security.oauth2.client.registration.ClientRegistration;
2823
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
2924

25+
import java.util.Collections;
26+
3027
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
3128

3229
/**
@@ -47,23 +44,11 @@ static HttpHeaders getTokenRequestHeaders(ClientRegistration clientRegistration)
4744
HttpHeaders headers = new HttpHeaders();
4845
headers.addAll(DEFAULT_TOKEN_REQUEST_HEADERS);
4946
if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) {
50-
String clientId = encodeClientCredential(clientRegistration.getClientId());
51-
String clientSecret = encodeClientCredential(clientRegistration.getClientSecret());
52-
headers.setBasicAuth(clientId, clientSecret);
47+
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
5348
}
5449
return headers;
5550
}
5651

57-
private static String encodeClientCredential(String clientCredential) {
58-
try {
59-
return URLEncoder.encode(clientCredential, StandardCharsets.UTF_8.toString());
60-
}
61-
catch (UnsupportedEncodingException ex) {
62-
// Will not happen since UTF-8 is a standard charset
63-
throw new IllegalArgumentException(ex);
64-
}
65-
}
66-
6752
private static HttpHeaders getDefaultTokenRequestHeaders() {
6853
HttpHeaders headers = new HttpHeaders();
6954
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveAuthorizationCodeTokenResponseClient.java

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515
*/
1616
package org.springframework.security.oauth2.client.endpoint;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
22-
import reactor.core.publisher.Mono;
23-
2418
import org.springframework.http.MediaType;
2519
import org.springframework.security.oauth2.client.registration.ClientRegistration;
2620
import org.springframework.security.oauth2.core.AuthorizationGrantType;
@@ -30,9 +24,10 @@
3024
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
3125
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
3226
import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
33-
import org.springframework.util.Assert;
3427
import org.springframework.web.reactive.function.BodyInserters;
3528
import org.springframework.web.reactive.function.client.WebClient;
29+
import org.springframework.util.Assert;
30+
import reactor.core.publisher.Mono;
3631

3732
import static org.springframework.security.oauth2.core.web.reactive.function.OAuth2BodyExtractors.oauth2AccessTokenResponse;
3833

@@ -79,9 +74,7 @@ public Mono<OAuth2AccessTokenResponse> getTokenResponse(OAuth2AuthorizationCodeG
7974
.accept(MediaType.APPLICATION_JSON)
8075
.headers(headers -> {
8176
if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) {
82-
String clientId = encodeClientCredential(clientRegistration.getClientId());
83-
String clientSecret = encodeClientCredential(clientRegistration.getClientSecret());
84-
headers.setBasicAuth(clientId, clientSecret);
77+
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
8578
}
8679
})
8780
.body(body)
@@ -98,16 +91,6 @@ public Mono<OAuth2AccessTokenResponse> getTokenResponse(OAuth2AuthorizationCodeG
9891
});
9992
}
10093

101-
private static String encodeClientCredential(String clientCredential) {
102-
try {
103-
return URLEncoder.encode(clientCredential, StandardCharsets.UTF_8.toString());
104-
}
105-
catch (UnsupportedEncodingException ex) {
106-
// Will not happen since UTF-8 is a standard charset
107-
throw new IllegalArgumentException(ex);
108-
}
109-
}
110-
11194
private static BodyInserters.FormInserter<String> body(OAuth2AuthorizationExchange authorizationExchange, ClientRegistration clientRegistration) {
11295
OAuth2AuthorizationResponse authorizationResponse = authorizationExchange.getAuthorizationResponse();
11396
BodyInserters.FormInserter<String> body = BodyInserters

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClient.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515
*/
1616
package org.springframework.security.oauth2.client.endpoint;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Set;
22-
import java.util.function.Consumer;
23-
24-
import reactor.core.publisher.Mono;
25-
2618
import org.springframework.core.io.buffer.DataBuffer;
2719
import org.springframework.core.io.buffer.DataBufferUtils;
2820
import org.springframework.http.HttpHeaders;
@@ -38,6 +30,10 @@
3830
import org.springframework.web.reactive.function.BodyInserters;
3931
import org.springframework.web.reactive.function.client.WebClient;
4032
import org.springframework.web.reactive.function.client.WebClientResponseException;
33+
import reactor.core.publisher.Mono;
34+
35+
import java.util.Set;
36+
import java.util.function.Consumer;
4137

4238
import static org.springframework.security.oauth2.core.web.reactive.function.OAuth2BodyExtractors.oauth2AccessTokenResponse;
4339

@@ -102,23 +98,11 @@ private Consumer<HttpHeaders> headers(ClientRegistration clientRegistration) {
10298
return headers -> {
10399
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
104100
if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) {
105-
String clientId = encodeClientCredential(clientRegistration.getClientId());
106-
String clientSecret = encodeClientCredential(clientRegistration.getClientSecret());
107-
headers.setBasicAuth(clientId, clientSecret);
101+
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
108102
}
109103
};
110104
}
111105

112-
private static String encodeClientCredential(String clientCredential) {
113-
try {
114-
return URLEncoder.encode(clientCredential, StandardCharsets.UTF_8.toString());
115-
}
116-
catch (UnsupportedEncodingException ex) {
117-
// Will not happen since UTF-8 is a standard charset
118-
throw new IllegalArgumentException(ex);
119-
}
120-
}
121-
122106
private static BodyInserters.FormInserter<String> body(OAuth2ClientCredentialsGrantRequest authorizationGrantRequest) {
123107
ClientRegistration clientRegistration = authorizationGrantRequest.getClientRegistration();
124108
BodyInserters.FormInserter<String> body = BodyInserters

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClient.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515
*/
1616
package org.springframework.security.oauth2.client.endpoint;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Collections;
22-
import java.util.function.Consumer;
23-
24-
import reactor.core.publisher.Mono;
25-
2618
import org.springframework.core.io.buffer.DataBuffer;
2719
import org.springframework.core.io.buffer.DataBufferUtils;
2820
import org.springframework.http.HttpHeaders;
@@ -40,6 +32,10 @@
4032
import org.springframework.util.StringUtils;
4133
import org.springframework.web.reactive.function.BodyInserters;
4234
import org.springframework.web.reactive.function.client.WebClient;
35+
import reactor.core.publisher.Mono;
36+
37+
import java.util.Collections;
38+
import java.util.function.Consumer;
4339

4440
import static org.springframework.security.oauth2.core.web.reactive.function.OAuth2BodyExtractors.oauth2AccessTokenResponse;
4541

@@ -104,23 +100,11 @@ private static Consumer<HttpHeaders> tokenRequestHeaders(ClientRegistration clie
104100
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
105101
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
106102
if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) {
107-
String clientId = encodeClientCredential(clientRegistration.getClientId());
108-
String clientSecret = encodeClientCredential(clientRegistration.getClientSecret());
109-
headers.setBasicAuth(clientId, clientSecret);
103+
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
110104
}
111105
};
112106
}
113107

114-
private static String encodeClientCredential(String clientCredential) {
115-
try {
116-
return URLEncoder.encode(clientCredential, StandardCharsets.UTF_8.toString());
117-
}
118-
catch (UnsupportedEncodingException ex) {
119-
// Will not happen since UTF-8 is a standard charset
120-
throw new IllegalArgumentException(ex);
121-
}
122-
}
123-
124108
private static BodyInserters.FormInserter<String> tokenRequestBody(OAuth2PasswordGrantRequest passwordGrantRequest) {
125109
ClientRegistration clientRegistration = passwordGrantRequest.getClientRegistration();
126110
BodyInserters.FormInserter<String> body = BodyInserters.fromFormData(

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveRefreshTokenTokenResponseClient.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515
*/
1616
package org.springframework.security.oauth2.client.endpoint;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Collections;
22-
import java.util.function.Consumer;
23-
24-
import reactor.core.publisher.Mono;
25-
2618
import org.springframework.core.io.buffer.DataBuffer;
2719
import org.springframework.core.io.buffer.DataBufferUtils;
2820
import org.springframework.http.HttpHeaders;
@@ -40,6 +32,10 @@
4032
import org.springframework.util.StringUtils;
4133
import org.springframework.web.reactive.function.BodyInserters;
4234
import org.springframework.web.reactive.function.client.WebClient;
35+
import reactor.core.publisher.Mono;
36+
37+
import java.util.Collections;
38+
import java.util.function.Consumer;
4339

4440
import static org.springframework.security.oauth2.core.web.reactive.function.OAuth2BodyExtractors.oauth2AccessTokenResponse;
4541

@@ -92,23 +88,11 @@ private static Consumer<HttpHeaders> tokenRequestHeaders(ClientRegistration clie
9288
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
9389
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
9490
if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) {
95-
String clientId = encodeClientCredential(clientRegistration.getClientId());
96-
String clientSecret = encodeClientCredential(clientRegistration.getClientSecret());
97-
headers.setBasicAuth(clientId, clientSecret);
91+
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
9892
}
9993
};
10094
}
10195

102-
private static String encodeClientCredential(String clientCredential) {
103-
try {
104-
return URLEncoder.encode(clientCredential, StandardCharsets.UTF_8.toString());
105-
}
106-
catch (UnsupportedEncodingException ex) {
107-
// Will not happen since UTF-8 is a standard charset
108-
throw new IllegalArgumentException(ex);
109-
}
110-
}
111-
11296
private static BodyInserters.FormInserter<String> tokenRequestBody(OAuth2RefreshTokenGrantRequest refreshTokenGrantRequest) {
11397
ClientRegistration clientRegistration = refreshTokenGrantRequest.getClientRegistration();
11498
BodyInserters.FormInserter<String> body = BodyInserters.fromFormData(

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/OAuth2ClientCredentialsGrantRequestEntityConverterTests.java

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,13 @@
1515
*/
1616
package org.springframework.security.oauth2.client.endpoint;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Base64;
22-
2318
import org.junit.Before;
2419
import org.junit.Test;
25-
2620
import org.springframework.http.HttpHeaders;
2721
import org.springframework.http.HttpMethod;
2822
import org.springframework.http.MediaType;
2923
import org.springframework.http.RequestEntity;
3024
import org.springframework.security.oauth2.client.registration.ClientRegistration;
31-
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
3225
import org.springframework.security.oauth2.core.AuthorizationGrantType;
3326
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3427
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
@@ -81,37 +74,4 @@ public void convertWhenGrantRequestValidThenConverts() {
8174
AuthorizationGrantType.CLIENT_CREDENTIALS.getValue());
8275
assertThat(formParameters.getFirst(OAuth2ParameterNames.SCOPE)).isEqualTo("read write");
8376
}
84-
85-
// gh-9610
86-
@SuppressWarnings("unchecked")
87-
@Test
88-
public void convertWhenSpecialCharactersThenConvertsWithEncodedClientCredentials()
89-
throws UnsupportedEncodingException {
90-
String clientCredentialWithAnsiKeyboardSpecialCharacters = "~!@#$%^&*()_+{}|:\"<>?`-=[]\\;',./ ";
91-
// @formatter:off
92-
ClientRegistration clientRegistration = TestClientRegistrations.clientCredentials()
93-
.clientId(clientCredentialWithAnsiKeyboardSpecialCharacters)
94-
.clientSecret(clientCredentialWithAnsiKeyboardSpecialCharacters)
95-
.build();
96-
// @formatter:on
97-
OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest = new OAuth2ClientCredentialsGrantRequest(
98-
clientRegistration);
99-
RequestEntity<?> requestEntity = this.converter.convert(clientCredentialsGrantRequest);
100-
assertThat(requestEntity.getMethod()).isEqualTo(HttpMethod.POST);
101-
assertThat(requestEntity.getUrl().toASCIIString())
102-
.isEqualTo(clientRegistration.getProviderDetails().getTokenUri());
103-
HttpHeaders headers = requestEntity.getHeaders();
104-
assertThat(headers.getAccept()).contains(MediaType.APPLICATION_JSON_UTF8);
105-
assertThat(headers.getContentType())
106-
.isEqualTo(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8"));
107-
String urlEncodedClientCredential = URLEncoder.encode(clientCredentialWithAnsiKeyboardSpecialCharacters,
108-
StandardCharsets.UTF_8.toString());
109-
String clientCredentials = Base64.getEncoder().encodeToString(
110-
(urlEncodedClientCredential + ":" + urlEncodedClientCredential).getBytes(StandardCharsets.UTF_8));
111-
assertThat(headers.getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Basic " + clientCredentials);
112-
MultiValueMap<String, String> formParameters = (MultiValueMap<String, String>) requestEntity.getBody();
113-
assertThat(formParameters.getFirst(OAuth2ParameterNames.GRANT_TYPE))
114-
.isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue());
115-
assertThat(formParameters.getFirst(OAuth2ParameterNames.SCOPE)).contains(clientRegistration.getScopes());
116-
}
11777
}

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -16,17 +16,12 @@
1616

1717
package org.springframework.security.oauth2.client.endpoint;
1818

19-
import java.net.URLEncoder;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Base64;
22-
2319
import okhttp3.mockwebserver.MockResponse;
2420
import okhttp3.mockwebserver.MockWebServer;
2521
import okhttp3.mockwebserver.RecordedRequest;
2622
import org.junit.After;
2723
import org.junit.Before;
2824
import org.junit.Test;
29-
3025
import org.springframework.http.HttpHeaders;
3126
import org.springframework.http.MediaType;
3227
import org.springframework.security.oauth2.client.registration.ClientRegistration;
@@ -87,35 +82,6 @@ public void getTokenResponseWhenHeaderThenSuccess() throws Exception {
8782
assertThat(body).isEqualTo("grant_type=client_credentials&scope=read%3Auser");
8883
}
8984

90-
// gh-9610
91-
@Test
92-
public void getTokenResponseWhenSpecialCharactersThenSuccessWithEncodedClientCredentials() throws Exception {
93-
// @formatter:off
94-
enqueueJson("{\n"
95-
+ " \"access_token\":\"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3\",\n"
96-
+ " \"token_type\":\"bearer\",\n"
97-
+ " \"expires_in\":3600,\n"
98-
+ " \"refresh_token\":\"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk\",\n"
99-
+ " \"scope\":\"create\"\n"
100-
+ "}");
101-
// @formatter:on
102-
String clientCredentialWithAnsiKeyboardSpecialCharacters = "~!@#$%^&*()_+{}|:\"<>?`-=[]\\;',./ ";
103-
OAuth2ClientCredentialsGrantRequest request = new OAuth2ClientCredentialsGrantRequest(
104-
this.clientRegistration.clientId(clientCredentialWithAnsiKeyboardSpecialCharacters)
105-
.clientSecret(clientCredentialWithAnsiKeyboardSpecialCharacters).build());
106-
OAuth2AccessTokenResponse response = this.client.getTokenResponse(request).block();
107-
RecordedRequest actualRequest = this.server.takeRequest();
108-
String body = actualRequest.getBody().readUtf8();
109-
assertThat(response.getAccessToken()).isNotNull();
110-
String urlEncodedClientCredentialecret = URLEncoder.encode(clientCredentialWithAnsiKeyboardSpecialCharacters,
111-
StandardCharsets.UTF_8.toString());
112-
String clientCredentials = Base64.getEncoder()
113-
.encodeToString((urlEncodedClientCredentialecret + ":" + urlEncodedClientCredentialecret)
114-
.getBytes(StandardCharsets.UTF_8));
115-
assertThat(actualRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Basic " + clientCredentials);
116-
assertThat(body).isEqualTo("grant_type=client_credentials&scope=read%3Auser");
117-
}
118-
11985
@Test
12086
public void getTokenResponseWhenPostThenSuccess() throws Exception {
12187
ClientRegistration registration = this.clientRegistration

0 commit comments

Comments
 (0)