When sending an OIDC token-request including client-secret (and client-id), the configured client-secret is changed: Any ending =
is converted to %3D
To Reproduce
authenticate against an OIDC provider that requires
spring.security.oauth2.client.registration.<provider>.client-authentication-method=client_secret_post
with a client-secret that ends with padding character =
That will result in a token-request where the padding character is replaced by unicode %3D
Expected behavior padding character for client-id should not be converted to unicode
Comment From: academey
I'd like to work on this issue.
Looking at the problem, it appears that the Base64 padding character '=' in client secrets is being incorrectly URL-encoded to '%3D' when using client_secret_post authentication method. This would prevent authentication with OIDC providers that require Base64-encoded client secrets.
I'll investigate the OAuth2 client authentication implementation to identify where the URL encoding is being applied and ensure proper handling of client secrets.
Comment From: SebastianDietrich
In the meantime I am not sure if the current behavior is correct. I first thought that the encoding would lead to an error with my OIDC provider, which now does not seem to be the case. Since URLs (and filenames) can't work with +, / and =, there is an encoding called BASE64url: + -> - (ASCII 2Dhex), / -> _ (ASCII 5Fhex), = -> %3d (or skipped, if the length is known) See https://datatracker.ietf.org/doc/html/rfc4648#section-5
So any OIDC provider should IMHO be able to work with %3d
Comment From: academey
@SebastianDietrich Thank you for pointing out RFC 4648 section 5. You're absolutely correct - the current behavior of URL-encoding the '=' padding character to '%3D' is actually compliant with both RFC 6749 (OAuth2) and RFC 4648 (Base64url).
After further investigation:
- RFC 6749 requires application/x-www-form-urlencoded
encoding for client_secret_post
- RFC 4648 section 5 states that padding '=' should be percent-encoded when used in URLs
- Spring Security's current behavior is standards-compliant
This means the issue is not a bug in Spring Security, but rather a compatibility problem with some OIDC providers that don't properly handle URL-encoded padding characters in client secrets.
I've already submitted PR #17674 which adds special handling to preserve Base64 padding characters. However, given this new understanding, I'd like to get the Spring Security team's perspective on whether:
- This should be treated as a compatibility enhancement rather than a bug fix
- The solution should be configurable (e.g., a flag to enable/disable padding preservation)
- The current standards-compliant behavior should be maintained
spring-security-team What are your thoughts on the best approach here?