Describe the bug
In the OAuth2 client authentication flow using HTTP Basic authentication, client credentials are Base64-decoded and then additionally passed through URLDecoder.decode().
ClientSecretBasicAuthenticationConverter.java
This results in incorrect handling of + characters in client secrets because URLDecoder follows application/x-www-form-urlencoded rules and converts + into a space.
As a result, valid client credentials containing + fail authentication.
This behavior appears to violate RFC 7617 (HTTP Basic Authentication), which specifies that credentials are raw strings encoded using Base64 and should not be URL-decoded.
To Reproduce
1. Register an OAuth2 client with a secret containing a + character, for example:
client-id: test-client
client-secret: abc+123
2. Send a token request using HTTP Basic authentication:
Authorization: Basic base64(test-client:abc+123)
3. Observe authentication failure due to credential mismatch.
Expected behavior
After Base64 decoding, the client credentials should be used as-is.
URLDecoder.decode() should not be applied when processing HTTP Basic authentication credentials.
Credentials containing + or percent-encoded characters should remain unchanged after Base64 decoding.
Minimal reproduction example:
String raw = "test-client:abc+123";
String encoded = Base64.getEncoder().encodeToString(raw.getBytes(StandardCharsets.UTF_8));
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
// current behavior (problematic)
String secret = URLDecoder.decode(decoded.split(":", 2)[1], StandardCharsets.UTF_8.name());
// expected behavior
String expectedSecret = decoded.split(":", 2)[1];
Authentication succeeds only when URL decoding is removed.
Describe the bug
In the OAuth2 client authentication flow using HTTP Basic authentication, client credentials are Base64-decoded and then additionally passed through URLDecoder.decode().
ClientSecretBasicAuthenticationConverter.java
This results in incorrect handling of + characters in client secrets because URLDecoder follows application/x-www-form-urlencoded rules and converts + into a space.
As a result, valid client credentials containing + fail authentication.
This behavior appears to violate RFC 7617 (HTTP Basic Authentication), which specifies that credentials are raw strings encoded using Base64 and should not be URL-decoded.
To Reproduce
1. Register an OAuth2 client with a secret containing a + character, for example:
client-id: test-client
client-secret: abc+123
2. Send a token request using HTTP Basic authentication:
Authorization: Basic base64(test-client:abc+123)
3. Observe authentication failure due to credential mismatch.
Expected behavior
After Base64 decoding, the client credentials should be used as-is.
URLDecoder.decode() should not be applied when processing HTTP Basic authentication credentials.
Credentials containing + or percent-encoded characters should remain unchanged after Base64 decoding.
Minimal reproduction example:
String raw = "test-client:abc+123";
String encoded = Base64.getEncoder().encodeToString(raw.getBytes(StandardCharsets.UTF_8));
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
// current behavior (problematic)
String secret = URLDecoder.decode(decoded.split(":", 2)[1], StandardCharsets.UTF_8.name());
// expected behavior
String expectedSecret = decoded.split(":", 2)[1];
Authentication succeeds only when URL decoding is removed.