Describe the bug Unless I'm really missing something (which I won't rule out ;)), the OpenID Connect Oauth2 client will explode when it receives an ID token signed by any algorithm other than RS256. Furthermore, the cardinality of the ClientRegistration -> Supported Signature Algorithm mapping seems to be 1:1 but I think it should be 1:many. Should the OpenID Provider choose to change signature algorithms, it should not break the client.
https://github.com/spring-projects/spring-security/blob/master/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenDecoderFactory.java#L87 shows the issue, whereby:
1. jwsAlgorithmResolver is declared as a 1:1 function of ClientRegistration to JwsAlgorithm
2. SignatureAlgorithm.RS256 is assumed to be signature algorithm
To Reproduce
1. Configure a spring boot app using OpenID Connect authentication
2. Configure a client registration in the OpenID Provider that uses an encryption algorithm other than RS256 -- ES256 is a good example
3. Attempt to execute an Oauth2 authorization code login flow
4. Observe an error message like [invalid_id_token] An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
Expected behavior
The OidcIdTokenDecoderFactory should be capable of working with either a predefined list of acceptable signature algorithms or support any algorithm for which a key exists in the OpenID Provider's JWKS.
Sample
Reproduction with a full OpenID Connect integration is non-trivial. Subsequent to opening the issue I'll attempt to spin up a unit test or code fragment to isolate the issue and demonstrate it.
Comment From: jgrandja
@JesseEstum I believe the error message is related to an application misconfiguration.
[invalid_id_token] An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
If the jwsAlgorithmResolver is returning ES256 for a specific ClientRegistration and the provider's JWKS endpoint does not return a ES256 key than it will fail.
Please review the reference on how to configure OidcIdTokenDecoderFactory.
If you're still having issues then I'll need you to put together a minimal sample that reproduces the issue. I know this can be challenging using an external provider but this sample will make it much easier.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: JesseEstum
Thank you, @jgrandja ! The link you provided did work for explicitly setting the expected ID Token signature algorithm to something other than RS256. This solves my acute problem.
More broadly, though, is there any mechanism to support an arbitrary signature algorithm or a predefined collection of signature algorithms for a single OpenID Provider? For example, if my OP uses ES256 today but decides to change to ES384 next week then my app would break. If the OP has the right ES384 keys published in its JWKS, couldn't spring-security just use them to authenticate the token?
Perhaps spring-security is designed to assert trust at a (Client Registration, Signature Algorithm)-pair level, not at a Client Registration level. Is that the design intent of the library?
Comment From: channyeintun
@jgrandja Thank you, This solves my problem.
Comment From: jgrandja
@JesseEstum
is there any mechanism to support an arbitrary signature algorithm or a predefined collection of signature algorithms for a single OpenID Provider? For example, if my OP uses
ES256today but decides to change toES384next week then my app would break
The Spring Boot property spring.security.oauth2.client.provider.[providerId].jwk-set-uri (see ClientRegistration) enables key rotation support.
For example, let's say the provider is signing tokens using ES256 today and tomorrow it rotates the primary signing key and starts using ES384, then the NimbusJwtDecoder associated with OidcIdTokenDecoderFactory will ultimately fetch the new set of keys from jwkSetUri and verify the signature. The re-fetch happens if it can't find the key in it's internal cache.
I'm not seeing any issue here so I'm going to close this as works as expected.
Again, if you are experiencing an issue then please put together a minimal sample as mention in this comment and I can re-open if need be.
Comment From: ldwqh0
@jgrandja Thanks. but how the "key rotation support" work? it not work for me.
I found that the RemoteJWKSet can be refresh jwks per 5 m. But it can not refresh the signatureAlgorithms.