passport-jwt icon indicating copy to clipboard operation
passport-jwt copied to clipboard

Multiple JWKS URIs

Open MeStrak opened this issue 3 years ago • 4 comments

Hi,

I'm working on adding auth to this app https://github.com/Sanofi-IADC/whispr implemented in NestJS.

The nature of the app is basically a backend which multiple clients can connect to, and I'm looking at how we can allow trusted clients to pass us their JWT from their own authentication provider to authenticate with the whispr API. I would like to be able to configure this dynamically by providing the different auth provider configurations as an array read at application startup.

My questions

  1. Is there a clean way of doing this already?
  2. If the answer to the first question is no, then could the changes described below be a sensible way for me to approach this?
  3. In passport-jwt strategy.js I saw the following comment. Does this mean there is a better way of passing this information, or is it recommended not to use these options at all?
//for backwards compatibility, still allowing you to pass
//audience / issuer / algorithms / ignoreExpiration
//on the options

Possible approach From a first code review I think that the change might be fairly straightforward to implement, although I have not yet tried any code changes as I wanted to check if there was an obviously better way of doing this.

Edit the strategy setup (in whispr code) to send an array of configurations instead of a single config:

    super([{
       secretOrKeyProvider: passportJwtSecret({
         cache: true,
         rateLimit: true,
         jwksRequestsPerMinute: 5,
         jwksUri: `${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`,
       }),

       jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
       audience: process.env.AUTH0_AUDIENCE,
       issuer: `${process.env.AUTH0_DOMAIN}/`,
       algorithms: ['RS256'],
      },
      {another config}
    ]);
  }

(but that array would be constructed dynamically).

In passport-jwt strategy.js

  • Edit function JwtStrategy(options, verify) to read the array and store options in an array
  • Edit function JwtStrategy.prototype.authenticate = function(req, options) to launch an async verification for each set of options in the options array, and return self.success when the first async request returns true

Thanks!

MeStrak avatar May 17 '21 17:05 MeStrak

I started a fork to work on this. It's WIP with some failing tests but looks promising.

https://github.com/MeStrak/passport-jwt.

MeStrak avatar May 20 '21 12:05 MeStrak

I finally got round to finishing the implementation and the @mestrak/passport-multi-jwt package is available here: https://www.npmjs.com/package/@mestrak/passport-multi-jwt.

Of course I'm definitely open to merging it with this package if requested by the maintainer.

MeStrak avatar Feb 03 '22 19:02 MeStrak

@MeStrak where are you getting passportJwtSecret from in your example above. What is that? (I am trying to get secret from URI)

coler-j avatar Feb 24 '23 20:02 coler-j

@MeStrak where are you getting passportJwtSecret from in your example above. What is that? (I am trying to get secret from URI)

Hi @coler-j , not sure what you mean exactly. passportJwtSecret is a method from the jwks-rsa library that builds a secret provider object that can be read by passport-jwt. You don't actually get the secret from the URI, it is the address of a JWKS (JSON web key set) which is used to verify that the JWT was issued by the auth provider.

Maybe this example will help? https://github.com/auth0/node-jwks-rsa/blob/master/examples/passport-demo/README.md

If you were specifically looking for something to handle multiple providers which was the original purpose of this old question, I ended up adapting passport-jwt and published passport-multi-jwt: https://www.npmjs.com/package/@mestrak/passport-multi-jwt.

MeStrak avatar Feb 24 '23 23:02 MeStrak