smallrye / smallrye-jwt

Apache License 2.0
75 stars 49 forks source link

Fix the docs - smallrye.jwt.resolve-remote-keys-at-startup and cache #818

Open zilinjak opened 3 months ago

zilinjak commented 3 months ago

Hey, lately I have been using smallrye jwt a lot. I have found bug where the cache of JWKS wasn't being refreshed. This ended up due to the implementation of smallrye.jwt.resolve-remote-keys-at-startup can you please fix the docs and add note that the smallrye.jwt.resolve-remote-keys-at-startup will mean that the keys will be fetched at start and cache WON'T be used.

sberyozkin commented 3 months ago

@zilinjak Hi, it is not a doc bug then but the runtime bug, as in this this case the keys must be refreshable

luneo7 commented 1 week ago

I've read the code and it seems that it is not a bug, as it sets to fetch only once by design, when we have resolve-remote-keys-at-startup set to true it doesn't use HttpsJWKS, but rather fetch the key only once from an URL and calls setPublicKeyContent or setDecryptionKeyContent in JWTAuthContextInfoProvider. And the HttpsJWKS is only created if setPublicKeyLocation was called in the JWTAuthContextInfoProvider, and when parseClaims is first called in DefaultJWTTokenParser, that will trigger a creation of a JwtConsumer that will trigger in first invocation the creation of KeyLocationResolver.

sberyozkin commented 5 days ago

@luneo7 Thanks, ideally though if the URL is HTTP(S) based, the resolvers would end up dealing with its HttpsJWKS representation (FYI, it is used even for HTTP-only content). It looks like the only way to fix it is, instead of trying to read the key content directly in JWTAuthContextInfoProvider#getOptionalContextInfo, is to do it by creating VerificationKeyResolver (and DecryptionKeyResolver), similarly to how it is done in DefaultJWTTokenParser, and pass these resolvers via JWTAuthContextInfo to avoid their creation in DefaultJWTTokenParser

luneo7 commented 5 days ago

@sberyozkin not related, but also found out that JwtConsumer is always created again when parsing a JWT, but as that class is thread safe it could be initialized just once and reused, is there a reason that it always recreated when parsing?