mikenicholson / passport-jwt

Passport authentication using JSON Web Tokens
MIT License
1.96k stars 213 forks source link

Multiple JWKS URIs #226

Open MeStrak opened 3 years ago

MeStrak commented 3 years ago

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

Thanks!

MeStrak commented 3 years ago

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 commented 2 years ago

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.

coler-j commented 1 year ago

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

MeStrak commented 1 year ago

@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.