0

I started using jose4j to validate Azure AD originating jwt tokens against the OpenedId Connect jwks it publishes. All in a restful environment which means no state.

To avoid recreating all the objects from scratch every time a request comes in and consequently jose4j retrieving the jwks again and again, I want to use caching.

The dilemma I have is what to cache:

  1. The serialized json jwks string and do so called out of band validation and when it fails get a new jwks.
  2. HttpsJwks
  3. HttpsJwksVerificationKeyResolver
  4. JwtConsumer

I was thinking JwtConsumer is the best. Any ideas on this if this is a good choice?

As the cache is shared over all restfull requests which are handled in a mulithreaded way (using cxf blueprint in Karaf) the JwtConsumer should be thread safe. Anybody know whether it is.

I was thinking to cache using ehcache or ConcurrentHashmap using the tid as the key.

David Makogon
  • 69,407
  • 21
  • 141
  • 189
JB007
  • 123
  • 8

1 Answers1

1

JwtConsumer is thread safe (as long as any custom Validators or Customizers used are also thread safe). However, cacheing and reusing the HttpsJwks object(s) is where you'll realize the vast majority of benefit because it internally caches the keys retrieved from the jwks endpoint. Holding on to HttpsJwks is what will prevent jose4j from retrieving the content of jwks endpoint again and again.

Brian Campbell
  • 2,293
  • 12
  • 13
  • Cool, so you suggest HttpsJwks and recreate the other objects on each subsequent rest request where I validate the token: HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(https_jwks); JwtConsumer jwtConsumer = new JwtConsumerBuilder() .setVerificationKeyResolver(httpsJwksKeyResolver) .setExpectedAudience(clientIdAuthserver) .setExpectedIssuer(issuerAuthServer) .build(); jwtClaims = jwtConsumer.processToClaims(authServerToken); Thanks! – JB007 Jun 18 '17 at 22:13
  • I was also looking at serializing HttpsJwks into a JSON String but i didn't see that possibility. Size wise compared to caching HttpsJwks it is mayb e better to serialize the string. Do you know how to do that? I didn't see an obvious method on HttpsJwks except for the one which returns a list of JsonWebKeys. – JB007 Jun 18 '17 at 22:32
  • You could get the list of JsonWebKeys and use a JsonWebKeySet serialize them to a JSON string. But I don't think there'd be much, if any, benefit. And it'd add a lot of work/complexity. – Brian Campbell Jun 22 '17 at 12:30
  • My final solution is/was to get the OpenID Connect document myself and extract the jwks_uri out of it, get in turn the JWKS. Both pieces of data I cache in Hazelcast, and use Jose4J to do what you call out of band validation of a received JWT from AzureAD. I invalidate the cache for a specific tid when InvalidJwtSignatureException is thrown as it might be due to a JWKS key roll over. get the discovery doc and JWKS again to re-validate the JWT and when it fails then again I know for sure the JWT is invalid and when it passes the cache is nicely updated. – JB007 Jun 22 '17 at 15:43