Skip to content

RemoteJwkSet is not refreshed when encountering an unknown KID #11621

Closed
@tinolazreg

Description

@tinolazreg

Describe the bug
If you are setting up a NimbusJwtDecoder using Spring Security, we have the possibility to provide a Cache that will be used for storing the JWK Set. This is a good feature, since we can then override the default TTL, instead of using DefaultJWKSetCache, which has a default refresh time of 5 minutes.

Reference to documentation: https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html#oauth2resourceserver-jwt-timeouts

The issue occurs when you use your own cache implementation, and you try to decode a JWT with an unknown KID. I would expect this to trigger a refresh of the JWK set, but this is not what is happening.

Example code of setup:

        var jwkSetCache = new ConcurrentMapCache("jwkSetCache", CacheBuilder.newBuilder()
                .expireAfterWrite(Duration.ofMinutes(30))
                .build().asMap(), false);
        var decoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
                .cache(jwkSetCache)
                .build();

We end up here with an unknown KID: https://bitbucket.org/connect2id/nimbus-jose-jwt/src/43b5435c548d70ce250afe6f932a6a55b3833bb8/src/main/java/com/nimbusds/jose/jwk/source/RemoteJWKSet.java#lines-486, and we expect the JWK set to be refetched.

The problem is that the NimbusJwtDecoder.java always uses the CachingResourceRetriever, even when it encounters an unknown KID: https://github.com/spring-projects/spring-security/blob/main/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtDecoder.java#L406-L407. This will lead to the JWK set only being fetched from the cache, and not refetched from the remote source.

To Reproduce

  1. Setup NimbusJwtDecoder with a Cache and remote JWK set.
  2. Try to decode a JWT signed with a KID not present in the JWK set.
  3. Expect NimbusJwtDecoder to refetch JWK set from jwksetUri.

If we don't specify a cache to the NimbusJwtDecoder builder, it works as expected. The jwk set is refetched when encountering a signed JWS with an unknown KID.

Expected behavior
I expect JWK set to be refetched when encountering a KID not present in the current cached JWK set.

Metadata

Metadata

Assignees

Labels

in: oauth2An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions