Search code examples
javajwtquarkusjwksmallrye

Quarkus verifying JWTs from multiple sources


Is there a way to allow JWTs from multiple sources?

I have a REST API that I only allow access to via Bearer Tokens authentication, and I really only need to verify these tokens, so I don't really need all the additions that OIDC brings.

Let's say I have Keycloak set up as an Identity Provider. I would configure quarkous-oidc accordingly. But now I also want to allow JWTs that I create in another service, for service to service communication. This is not an identity provider, but i rather just use smallrye-jwt to create some "internal" tokens.

So it actually seems that I would rather use quarkus-smallrye-jwt, but I can't configure it for multiple tenants.

I think consolidating the keys in a JWKS and providing that to quarkus-smallrye-jwt would eventually work. But maybe there is a more elegant solution that I didn't see.


Solution

  • With microprofile-jwt(smallrye-jwt) you have an option to use JWKS(Json Web Key Set) as your mp.jwt.verify.publickey.location property. That allows you to trust tokens issued by multiple issuers. However, you will not be able to, for example, validate multiple values in issuer field of the jwt token as it only supports single value, or define different config per issuer.

    You can create the JWKS manually, combining the key info from your auth providers and embedding/mounting it in your app, or you can implement some endpoint that produces it dynamically(e.g. it would periodically call the 2 Keycloaks JWKS urls and combine the output producing new JWKS)

    If you need more control over the validation, then you'll need to create your own implementation and integrate it with MP JWT/Quarkus. One option could be to provide a custom JWTCallerPrincipalFactory to smallrye-jwt - see docs about custom factories. There you could read any custom config (e.g. my.app.jwt.issuers=trustedIssuer1,trustedIssuer2 and handle the validation yourself, maybe reusing classes already provided by smallrye (JWTAuthContextInfo, JWTParser...)