awslabs / aws-jwt-verify

JS library for verifying JWTs signed by Amazon Cognito, and any OIDC-compatible IDP that signs JWTs with RS256, RS384, RS512, ES256, ES384, and ES512
Apache License 2.0
621 stars 44 forks source link

[QUESTION] Does this library support JWKS if kty value is not only RSA #68

Closed reachmehere89 closed 2 years ago

reachmehere89 commented 2 years ago

Question Does this library support JWKS if kty value is not only RSA My IDP provider have kty values RSA and EC. Library fails as it mandates n and e as mandatory parameters which are not there in case kty is EC

Versions Which version of aws-jwt-verify are you using? Latest Are you using the library in Node.js or in the Web browser? Node js If Node.js, which version of Node.js are you using? (Should be at least 14) 14.x If Web browser, which web browser and which version of it are you using? NA If using TypeScript, which version of TypeScript are you using? (Should be at least 4) NA

ottokruse commented 2 years ago

Hi @reachmehere89, thanks for the question.

Currently only RSA is supported (RS256, RS384, RS512) as you've found, however we'd be interested in expanding algorithm support.

Which provider is that? Can you share the JWKS?

reachmehere89 commented 2 years ago

This is our company IDP and unfortunately I can't share it here(at least to be on safer side, though I can check if it can be shared). But my suggestion would be to only validate for jwks where kty is RSA only and ignore rest as other algorithms are not supported.

ottokruse commented 2 years ago

Okay so IIUC you want to verify a RSA-signed JWT, but the public key is includes in a JWKS that includes non-RSA public keys (that do not have n and e).

You're right, currently this lib requires the entire JWKS, all JWKs in it, to have n and e.

https://github.com/awslabs/aws-jwt-verify/blob/6476a42d34a0992356a2c12600ab5cd5aa1b651d/src/jwk.ts#L25-L31 https://github.com/awslabs/aws-jwt-verify/blob/6476a42d34a0992356a2c12600ab5cd5aa1b651d/src/jwk.ts#L108-L114

Agree that it seems fair to skip that check for all JWKs, and instead only perform it for the JWK that's actually being used.

For the time being, if you want, you can work around it, with a custom fetcher:

import { JwtRsaVerifier } from "aws-jwt-verify";
import { SimpleJwksCache, Jwks } from "aws-jwt-verify/jwk";
import { SimpleJsonFetcher, JsonFetcher } from "aws-jwt-verify/https";
import { Json } from "aws-jwt-verify/safe-json-parse";

// Please forgive the TypeScript shenanigans
class CustomJsonFetcher extends SimpleJsonFetcher {
  fetch = async <ResultType extends Json>(...args: Parameters<JsonFetcher["fetch"]>) => {
    const jwks = await super.fetch<Jwks>(...args);
    jwks.keys = jwks.keys.filter((key) => key.n && key.e); // Or: jwks.keys.filter(key => key.kty === "RSA")
    return jwks as unknown as ResultType;
  };
}

const verifier = JwtRsaVerifier.create(
  {
    issuer: "<your-issuer>",
    audience: "<your-audience>",
    jwksUri: "<your-jwks-uri>",
  },
  {
    jwksCache: new SimpleJwksCache({
      fetcher: new CustomJsonFetcher(),
    }),
  }
);
reachmehere89 commented 2 years ago

Thanks for the suggestion. Will give it a try and post how it goes

ottokruse commented 2 years ago

Fix is included in v3.1.0