GithubHelp home page GithubHelp logo

auth0 / node-jwks-rsa Goto Github PK

View Code? Open in Web Editor NEW
814.0 16.0 232.0 1.31 MB

A library to retrieve RSA public keys from a JWKS (JSON Web Key Set) endpoint.

License: MIT License

JavaScript 97.86% TypeScript 2.14%
dx-sdk

node-jwks-rsa's Introduction

A library to retrieve signing keys from a JWKS (JSON Web Key Set) endpoint.

Release Codecov Downloads License CircleCI

๐Ÿ“š Documentation - ๐Ÿš€ Getting Started - ๐Ÿ’ฌ Feedback

Documentation

  • Examples - documentation of the options and code samples for common scenarios.
  • Docs Site - explore our Docs site and learn more about Auth0.

Getting Started

Installation

Using npm in your project directory run the following command:

npm install --save jwks-rsa

Supports all currently registered JWK types and JWS Algorithms, see panva/jose#262 for more information.

Configure the client

Provide a JWKS endpoint which exposes your signing keys.

const jwksClient = require('jwks-rsa');

const client = jwksClient({
  jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
  requestHeaders: {}, // Optional
  timeout: 30000 // Defaults to 30s
});

Retrieve a key

Then use getSigningKey to retrieve a signing key that matches a specific kid.

const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
const key = await client.getSigningKey(kid);
const signingKey = key.getPublicKey();

Feedback

Contributing

We appreciate feedback and contribution to this repo! Before you get started, please see the following:

Raise an issue

To provide feedback or report a bug, please raise an issue on our issue tracker.

Vulnerability Reporting

Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

What is Auth0?

Auth0 Logo

Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?

This project is licensed under the MIT license. See the LICENSE file for more info.

node-jwks-rsa's People

Contributors

aaronmoat avatar adamjmcgrath avatar amrsalama avatar brunokrebs avatar christianliebel avatar cocojoe avatar crew-security avatar damieng avatar dankell avatar davidpatrick avatar dependabot[bot] avatar ecasilla avatar evansims avatar fnberta avatar frederikprijck avatar gconnolly avatar igorsechyn avatar jfromaniello avatar jimmyjames avatar jonpacker avatar lbalmaceda avatar luisrudge avatar manpreet-compro avatar nshahri avatar okko avatar panva avatar sandrinodimattia avatar snyk-bot avatar widcket avatar xmlking avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-jwks-rsa's Issues

node-jwks-rsa library creates incorrect PK from mod/exp from JWKS

the node-jwks-rsa library is creating an incorrect public key from the modulus / exponent of any Key ID in our JWKS URI.

Example:

Key ID 1 including the modulus / exponent:
{
"kty": "RSA",
"alg": "RSA256",
"use": "sig",
"kid": "1",
"n": "23631293961801179230154925007272778099637513643444060811747394163364241446299855803951645705848124426292859717395062987713399401319042217226130633263747925751881712317848573016636839068415437227125215894086621836191192638691340404866267214828293405939844497232806818227923053771324444775139123760096149247934944668624999977856824981822441847379834305862693515614724613514334815933149557971254406874081565126561019072286547226934234795431951664684285106379044889910638680445274415539072737016344754988844013254133896736050027442670090679515202745363444604213562920199191119814867373072219279937402409358313722130399693",
"e": "65537"
}

Calculating public key (our side:)
public void printCertFromExpMod() throws Exception {
// long m =
// 23631293961801179230154925007272778099637513643444060811747394163364241446299855803951645705848124426292859717395062987713399401319042217226130633263747925751881712317848573016636839068415437227125215894086621836191192638691340404866267214828293405939844497232806818227923053771324444775139123760096149247934944668624999977856824981822441847379834305862693515614724613514334815933149557971254406874081565126561019072286547226934234795431951664684285106379044889910638680445274415539072737016344754988844013254133896736050027442670090679515202745363444604213562920199191119814867373072219279937402409358313722130399693;
BigInteger mod = new BigInteger(
"23631293961801179230154925007272778099637513643444060811747394163364241446299855803951645705848124426292859717395062987713399401319042217226130633263747925751881712317848573016636839068415437227125215894086621836191192638691340404866267214828293405939844497232806818227923053771324444775139123760096149247934944668624999977856824981822441847379834305862693515614724613514334815933149557971254406874081565126561019072286547226934234795431951664684285106379044889910638680445274415539072737016344754988844013254133896736050027442670090679515202745363444604213562920199191119814867373072219279937402409358313722130399693");
BigInteger exp = new BigInteger("65537");

         RSAPublicKeySpec spec = new RSAPublicKeySpec(mod, exp);
         KeyFactory factory = KeyFactory.getInstance("RSA");
         PublicKey pub = factory.generatePublic(spec);

         byte[] pubKey = pub.getEncoded();
         String strPubKey = Base64.encodeBase64String(pubKey);
         System.out.println(strPubKey);

   }

Our side output: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzIm8XmKjQ8yN2JZOHt3BsFGCM1Uc6MUd9ECL2MoYrl8gnCbffo/utWnGrvXyJORGpVDjeVaJLyqxk+BSs8TIMuC7bQCQcrgK9hzOXzExQN5roHVAnW30eTnPEfJa+cds+J9qTKgODcX/FrGZ7w+y9r0eafEF3ZXITJZDYyLQMsGMuz37ktq9BZffCz+lQ4SUyr3FSZ7YZPpjdCbvcHmhw6mcmgM67BLdiejrUPXdPyKE3GzCuXWqnDFZRW4nt2PvKTfYgcTA8J4gs/YaeYXnlfam+631BqJnATJrQIxz6YdOyo2C8ImpX+qNrrMfbE1+HdzU08pruqoZcZUdL8BzQIDAQAB

--

Calling the function on our test application side using the node-jwks-rsa library:
client.getSigningKey(kid, (err, key) => {
const pubKey = key.rsaPublicKey;
console.log('public key: ' + pubKey)
});

Output of key calculation through node-jwks-rsa for same key ID (1):
public key: -----BEGIN RSA PUBLIC KEY-----
MIIB2QKCAc8A2363129396180117923015492500727277809963751364344406
0811747394163364241446299855803951645705848124426292859717395062
9877133994013190422172261306332637479257518817123178485730166368
3906841543722712521589408662183619119263869134040486626721482829
3405939844497232806818227923053771324444775139123760096149247934
9446686249999778568249818224418473798343058626935156147246135143
3481593314955797125440687408156512656101907228654722693423479543
1951664684285106379044889910638680445274415539072737016344754988
8440132541338967360500274426700906795152027453634446042135629201
9919111981486737307221927993740240935831372213039969AgQA6553
-----END RSA PUBLIC KEY-----

As you can see, the generated public key above (MIIB2QKCA) is different than the correct public key (MIIBIjANB), thus we get a signature verification failure.

Can you please advise? Am I doing something wrong, or is there an issue with the calculation on the library side? I would be glad to provide any more detail as needed. Thanks

hapiJwt2KeyAsync is undefined

When using version 1.2.1, the function hapiJwt2KeyAsync is undefined. See below:

        options: {
            complete: true,
            key: JwksRsa.hapiJwt2Key({ // if changed to hapiJwt2KeyAsync this would fail
                cache: true,
                rateLimit: true,
                jwksRequestsPerMinute: 5,
                jwksUri: options.auth0Uri
            }),
            verifyOptions: {
                audience: options.auth0Audience,
                issuer: options.auth0Issuer,
                algorithms: ['RS256']
            },
            validate: internals.validate
        }

Any thoughts?

Thanks!

Signing Keys empty when "use": "sig" field not provided

My auth provider stores keys in a following format:

{
  "keys": [{
    "kty": "RSA",
    "kid": "XXX",
    "n": "XXX",
    "e": "XXX"
  }]
}

As you can see, it's missing use param. According to JWK RFC this param is:

OPTIONAL, unless the application requires its presence.

To be honest I have difficulties to interpret this part. The bottom line is that I cannot make it work with my auth provider, because of this line:
https://github.com/auth0/node-jwks-rsa/blob/master/src/JwksClient.js#L52

Would it be possible to make use param optional?

Missing "use":"sig" in some provider's webkey causing JwksError: The JWKS endpoint did not contain any signing keys

I encountered a provider (OneLogin) that did not specify "use":"sig" for their webkey.

This will cause the jwksClient to crash:

JwksError: The JWKS endpoint did not contain any signing keys
    at /home/runner/node_modules/jwks-rsa/lib/JwksClient.js:122:21
    at Request._callback (/home/runner/node_modules/jwks-rsa/lib/JwksClient.js:94:16)
    at Request.self.callback (/home/runner/node_modules/request/request.js:185:22)
    at Request.emit (events.js:180:13)
    at Request.<anonymous> (/home/runner/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:180:13)
    at IncomingMessage.<anonymous> (/home/runner/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:272:13)
    at IncomingMessage.emit (events.js:185:15)
    at endReadableNT (_stream_readable.js:1106:12)
  name: 'JwksError',
  message: 'The JWKS endpoint did not contain any signing keys' }
undefined
Process crashed with: TypeError: Cannot read property 'publicKey' of undefined
    at client.getSigningKey (evalmachine.<anonymous>:15:28)
    at /home/runner/node_modules/jwks-rsa/lib/JwksClient.js:51:18
    at /home/runner/node_modules/jwks-rsa/lib/JwksClient.js:122:18
    at Request._callback (/home/runner/node_modules/jwks-rsa/lib/JwksClient.js:94:16)
    at Request.self.callback (/home/runner/node_modules/request/request.js:185:22)
    at Request.emit (events.js:180:13)
    at Request.<anonymous> (/home/runner/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:180:13)
    at IncomingMessage.<anonymous> (/home/runner/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:272:13)

I think this PR in another library solves a similar problem: IdentityModel/IdentityModel.OidcClient#77
Also a similar issue in the above library that raised by another user: IdentityModel/IdentityModel.OidcClient#65

And after taking a glance at the client code, I think here might be the place for improvement/enhancement: https://github.com/auth0/node-jwks-rsa/blob/master/src/JwksClient.js#L52
We could change this line from:

.filter(key => key.use === 'sig' && key.kty === 'RSA' && key.kid && ((key.x5c && key.x5c.length) || (key.n && key.e)))

to:

.filter(key => (key.use === 'sig' || key.use === null) && key.kty === 'RSA' && key.kid && ((key.x5c && key.x5c.length) || (key.n && key.e)))

Thanks for looking and helping in advance !

snyk vulnerabilities

My latest report highlighted two vulnerabilities

Regular Expression Denial of Service (ReDoS)
Vulnerable module: lodash
Introduced through: [email protected]
Detailed paths and remediation
Introduced through: [email protected] โ€บ [email protected] โ€บ [email protected] โ€บ [email protected]
Prototype Pollution
Vulnerable module: lodash
Introduced through: [email protected]
Detailed paths and remediation
Introduced through: [email protected] โ€บ [email protected] โ€บ [email protected] โ€บ [email protected]

Thanks,
Shane.

Error: Cannot find module 'jsonwebtoken'

Hello everyone,

As I understand with the last update on May 9, 2019 lib integrated with 'passport-jwt' which use 'jsonwebtoken' inside.
So, for now, 'jsonwebtoken' exist only in devDependencies package.json and it will be a problem because lib using it not only for dev.
8760bb2#diff-df829a25c0749c2341fe4d27680067a9

For now, I need to install 'jsonwebtoken' manually.

Thanks,
Andrew

The JWKS endpoint did not contain any signing keys

Looking closer within JwksClient.js, it seems to not filter out the keys properly. By default, the kty value in this was RSA, but our Ping implementation used EC keys. I swapped that, but the following code produces an undefined list of "keys"...

var signingKeys = keys.filter(function (key) { return key.use === 'sig' && key.kty === 'EC' && key.kid && (key.x5c && key.x5c.length || key.n && key.e); }).map(function (key) { if (key.x5c && key.x5c.length) { return { kid: key.kid, nbf: key.nbf, publicKey: (0, _utils.certToPEM)(key.x5c[0]) }; } else { return { kid: key.kid, nbf: key.nbf, rsaPublicKey: (0, _utils.rsaPublicKeyToPEM)(key.n, key.e) }; } });

This is our JWKS file example:
{"keys":[{"kty":"EC","kid":"k9","use":"sig","alg":"ES512","x":"<value>","y":"<value>","crv":"P-521"},{"kty":"EC","kid":"k8","use":"sig","alg":"ES384","x":"<value>","y":"<value>","crv":"P-384"},{"kty":"EC","kid":"k7","use":"sig","alg":"ES256","x":"<value>","y":"<value>","crv":"P-256"},{"kty":"EC","kid":"k3","use":"sig","alg":"ES512","x":"<value>","y":"<value>","crv":"P-521"},{"kty":"EC","kid":"k2","use":"sig","alg":"ES384","x":"<value>","y":"<value>","crv":"P-384"},{"kty":"EC","kid":"k1","use":"sig","alg":"ES256","x":"<value>","y":"<value>","crv":"P-256"},{"kty":"EC","kid":"jx","use":"sig","alg":"ES512","x":"<value>","y":"<value>","crv":"P-521"},{"kty":"EC","kid":"jw","use":"sig","alg":"ES384","x":"<value>","y":"<value>","crv":"P-384"},{"kty":"EC","kid":"jv","use":"sig","alg":"ES256","x":"<value>","y":"<value>","crv":"P-256"}]}

Getting jwks Failure: Error: SSL Error: SELF_SIGNED_CERT_IN_CHAIN

When trying to get the JWT keys to validate a token, the request fails when the environment has a self-signed cert in the chain behind enterprise proxy.
jwks Fetching keys from 'https://authserver/oauth2/default/v1/keys' +0ms
jwks Failure: Error: SSL Error: SELF_SIGNED_CERT_IN_CHAIN
at Request.onRequestResponse (node_modules/request/request.js:952:24)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:551:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:115:23)
at TLSSocket.socketOnData (_http_client.js:440:20)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11) +181ms
Error: SSL Error: SELF_SIGNED_CERT_IN_CHAIN
at Request.onRequestResponse (node_modules/request/request.js:952:24)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:551:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:115:23)
at TLSSocket.socketOnData (_http_client.js:440:20)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)

Support for EC JWK format?

We've been using this library to obtain the key matching the supplied kid from a 3rd party system that just moved to use EC format JWK rather than RS.

The library returns null for the key if the format isn't RS256 without any other logging, which took us a while to identify the problem.

Is there a recommended approach for also supporting EC keys for lookup from a JSON Web Key Set URL?

hapi v17 support

hi is there any work currently being done to update the hapi integration to support the lastest version of hapijs

Error in node_modules/jwks-rsa/node_modules/lru-memoizer/index.js:18

I am using Node as backend and was wiring it up with RS256 spec. Installed all the packages mentioned here https://auth0.com/docs/quickstart/backend/nodejs

When I start my server I get below error from one of the libraries. It's sourcing from here, jwks-rsa/node_modules/lru-memoizer/index.js:18

_.extend(load, { del }, options); ^ SyntaxError: Unexpected token } at exports.runInThisContext (vm.js:73:16) at Module._compile (module.js:443:25) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Module.require (module.js:365:17) at require (module.js:384:17) at Object.<anonymous> (/Users/viditsaxena/Documents/unwander/unwander-services/node_modules/jwks-rsa/lib/wrappers/cache.js:45:20) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Module.require (module.js:365:17) at require (module.js:384:17) at Object.<anonymous> (/Users/viditsaxena/Documents/unwander/unwander-services/node_modules/jwks-rsa/lib/wrappers/index.js:8:14) at Module._compile (module.js:460:26)

[typescript][typings] Error with existing typings of version 1.2.0

Observed behavior (tsc output):

Running "ts:build" (ts) task
Compiling...
Cleared fast compile cache for target: build
Using tsc v2.4.0
src/server/routes/token_authentication.ts(19,16): error TS2551: Property 'expressJwtSecret' does not exist on type 'typeof JwksRsa'. Did you mean 'ExpressJwtSecret'?

>> 1 non-emit-preventing type warning  
>> Error: tsc return code: 2
Warning: Task "ts:build" failed. Use --force to continue.

Aborted due to warnings.

Expected behavior:
Property exists on type JwksRsa

Example code (express middleware)

import * as express from "express";
import * as jwt from "express-jwt";
import * as jwks from "jwks-rsa";

const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN || "no-auth0-domain.available";

/**
 * Create base validation configuration for JWT created by Auth0
 */
const BASE_CONFIG: jwt.Options = {
  secret: jwks.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://${AUTH0_DOMAIN}/.well-known/jwks.json`
  }),
  audience: "urn:operational_portal",
  issuer: `https://${AUTH0_DOMAIN}/`,
  algorithms: ["RS256"]
};

const CREDENTIALS_OPTIONAL_CONFIG: jwt.Options = Object.assign({}, BASE_CONFIG, {
  credentialsRequired: false
});

export function authenticationRequired(req: express.Request, res: express.Response, next: any) {
  return jwt(BASE_CONFIG)(req, res, next);
}

export function getUser(req: express.Request, res: express.Response, next: any) {
  return jwt(CREDENTIALS_OPTIONAL_CONFIG)(req, res, next);
}

koaJwtSecret Typescrypt typing

Hi,

I don't understand the signature of koaJwtSecret.

In the file index.d.ts the koaJwtSecret definition is:

function koaJwtSecret(options: JwksRsa.Options): (name: string, scheme: string, options?: any) => void;

but the code in lib/integrations.ts doesn't match this signature. It return the function secretProvider that:

  • take one argument : the header of the token to extract "alg" and "kid"
  • return a string and not void: the public key or the rsa public key

I think the signature should be:

function koaJwtSecret(options: JwksRsa.Options): (header: object) => Promise<string>;

Is it an error or didn't understand?

Allow custom headers in request

Currently it is not possible to set custom headers when requesting the keys.

In our case this lead to the following problem: the "request" module sets the Accept header to application/json when json: true is used and no Accept header is set explicitly. See:

request({ json: true, uri: this.options.jwksUri, strictSSL: this.options.strictSsl }, (err, res) => {

https://github.com/request/request/blob/a92e138d897d78ce19dd70bd1ad271c7f9c6a23d/request.js#L1279-L1281

However if the server that stores the JWKS is configured to return a application/jwk-set+json content-type, a request with Accept: application/json is declined with a 406 error. To fix this we need to set the Accept header to either application/jwk-set+json or *.

It would be great if custom headers could be configured in the options.

SSL Error: X.jwks.json does not support SSL

Hey guys I get this when pointing to my Auth0 jwks file:

https://{my tenant}.auth0.com/.well-known/jwks.json

I realize that there is an option to override this error - but why is it happening? The Auth-0 endpoint is https, isn't it? Is it generating the error from my dev server? If so the message is misleading.

Cannot GET /.well-known/jwks.json

Seems like request is parsing the jwksUri and it ends up removing part of it so the request to fetch the keys fails. I am guessing this is because there is a dot in the uri i.e. in /.well-known/.
This is pretty much breaking the whole library for me.

I'm running the simple quick start example that you get after you have created an API in auth0, on node v6.9.5

Any ideas what might be happening and how it could be fixed? Thanks

Importing jkws-rsa creates unhandled promise

Our team uses Jest for testing with the detectOpenHandlers flag. This option helps us to catch mistakes when we forget to await promises.

When trying to import the node-jwks-rsa library we noticed that our tests started to fail with an open handle error. When debugging we noticed this happens whenever we import the package: import jwksRsa from "jwks-rsa";

Here's what Jest outputs:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

    PROMISE

          at Function.resolve (<anonymous>)
      at runInContext (node_modules/lodash/lodash.js:6069:36)
      at Object.<anonymous> (node_modules/lodash/lodash.js:17078:11)
      at Object.<anonymous> (node_modules/lodash/lodash.js:17105:3)
      at Object.<anonymous> (node_modules/lru-memoizer/index.js:2:20)

In debugging this we commented out require('lru-memoizer') and the error went away. It seems like this library probably creates the promise as a side effect at some point.

Webpack/VueJS conflict

Whenever I import this module, compilation fails with these errors:

ERROR  Failed to compile with 6 errors                                                                                                                                                                  10:22:10

These dependencies were not found:

* fs in ./node_modules/request/lib/har.js
* net in ./node_modules/forever-agent/index.js, ./node_modules/tough-cookie/lib/cookie.js and 1 other
* tls in ./node_modules/forever-agent/index.js, ./node_modules/tunnel-agent/index.js

When I npm install --save fs net tls, the first error persists and I can't run the code.

This only happens with this module. I'm using VueJS 2.5.16

Check cert validity

I was looking at the tests and checked the mock data. More specifically the certificate used for mocks in the tests:

export const publicKey = `-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIJAP0uzO56NPNDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTYwODAyMTIyMjMyWhcNMTYwOTAxMTIyMjMyWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvw
UAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03G
UnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQABo4GnMIGkMB0G
A1UdDgQWBBR7ZjPnt+i/E8VUy4tinxi0+H5vbTB1BgNVHSMEbjBsgBR7ZjPnt+i/
E8VUy4tinxi0+H5vbaFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAP0uzO56
NPNDMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAnMA5ZAyEQgXrUl6J
T/JFcg6HGXj9yTy71EEMVp3Md3B8WwDvs+di4JFcq8FKSoGtTY4Pb5WE9QVUAmwE
sSQoETNYW3quRmYJCkpIHWnvUW/OAf2/Ejr6zXquhBC6WoCeKQuesMvo2qO1rStC
UWahUh2/RQt9XozEWPWJ9Oe6a7c=
-----END CERTIFICATE-----`;

It has the following props:
selection_104
And is used for example here:
it('should work if the token matches a signing key', (done) => {
const app = new Koa();
app.use(koaJwt({
debug: true,
secret: jwksRsa.koaJwtSecret({
jwksUri: 'http://localhost/.well-known/jwks.json'
}),
algorithms: ['RS256']
}));
app.use((ctx) => {
ctx.body = ctx.state.user;
ctx.status = 200;
});
const token = createToken(privateKey, '123', { sub: 'john' });
jwksEndpoint('http://localhost', [ { pub: publicKey, kid: '123' } ]);
request(app.listen())
.get('/')
.set('Authorization', `Bearer ${ token }`)
.expect(200)
.end((err, res) => {
expect(res.body.sub).to.equal('john');
done();
});

The fact the in the tests JWTs are being recognized as valid when I run these tests today makes be believe, that the validity of the cert is not checked (The cert is invalid because it is not 2016 any more).

  • The integrations for koa, express, etc, in this package should check the validity of the cert provided by the JWKSClient. At least the lifetime and the hostname.
  • The variable publicKey should be renamed to certificate because it is a cert, not a public key, which is quite confusing.

dev dependency listed as runtime dependency

The package.json contains:
"@types/express-jwt": "0.0.34",
as a runtime dependency. This should be moved to dev dependencies, since types are not needed at runtime.

The declaration file in express-jwt adds properties like user to the Express.Request interface, which conflicts with other libraries an app might be using (like passport), which try to declare the same property on Express.Request.

hapiJwt2KeyAsync rejected with null

Hi,

Some non-valid access tokens in hapiJwt2KeyAsync causes "Error: Cannot throw non-error object"

Steps:

  1. Add a random character beginning of the JWT access key.
  2. Use invalid key for authentication
scheme: "jwt",
  options: {
    complete: true,
    key: jwksRsa.hapiJwt2KeyAsync({
      cache: false,
      rateLimit: true,
      jwksRequestsPerMinute: 5,
      jwksUri: "https://XXXX.eu.auth0.com/.well-known/jwks.json",
    }),
    verifyOptions: {
      audience: "https://api.XXXX.com",
      issuer: "https://XXXX.eu.auth0.com/",

      algorithms: ["RS256"],
    },
    validate: validate,
  },

hapiJwt2KeyAsync() rejects with null in file jwks-rsa/lib/integrations/hapi.js

module.exports.hapiJwt2KeyAsync = function (options) {
  var secretProvider = module.exports.hapiJwt2Key(options);
  return function (decoded) {
    return new Promise(function (resolve, reject) {
      var cb = function cb(err, key) {
        !key || err ? reject(err) : resolve({ key: key });
      };
      secretProvider(decoded, cb);
    });
  };
};

Kind Regards,

Caching concern

We have set the rate limit to 1 per minute and set the cache to true, however, we are still getting a high number of rate limit errors from our application. This seems like a bug in the caching function. Can anyone else comment on this?

cache: true,
 jwksRequestsPerMinute: 1,
jwksUri: "https://<our_auth0>.auth0.com/.well-known/jwks.json",
rateLimit: true

Here is the error. This typically occurs when we are returning 50+ items that each require authentication from a search result:

{name: "JwksError", message: "Too Many Requests"}
message
:
"Too Many Requests"
name
:
"JwksError"

TypeError: Object [object Object] has no method 'find'

Hi guys,

I found bug. Here is snippet how, I'm using jwks-rsa package with log added bellow.

const jwtMiddleware = require("express-jwt");
const jwksRsa = require("jwks-rsa");
const router = Router();

export class Notification {
    router: any;

    constructor(private env: any) {
        this.router = router.use(jwtMiddleware({
            secret: jwksRsa.expressJwtSecret({
                strictSsl: false,
                jwksUri: env.JSON_WEB_KEY_SET
            })
        }));

        /**
         * @swagger
         * /notifications:
         *   post:
         *     tags:
         *       - Notifications
         *     description: Creates new nofication thru Socket.io
         *     produces:
         *       - application/json
         *     responses:
         *       200:
         *         description: Success status code
         *     parameters:
         *       - name: notify
         *         in: body
         *         description: Notify definition
         *         required: true
         *         schema:
         *           $ref: '#/definitions/Notify'
         *       - name: authorization
         *         in: header
         *         type: string
         *         required: true
         *         default: 'Bearer '
         *         description: 'Usage: Bearer xxx'
         */
        this.router = router.post("/", (req: ShRequest, res: Response) => {
            const notify = <Notify>req.body;

            // ... code lives here

            res.sendStatus(200);
        });
    }
};
TypeError: Object [object Object] has no method 'find'
    at /usr/lib/realtime_notifications/node_modules/jwks-rsa/lib/JwksClient.js:54:24
    at /usr/lib/realtime_notifications/node_modules/jwks-rsa/lib/JwksClient.js:126:16
    at Request._callback (/usr/lib/realtime_notifications/node_modules/jwks-rsa/lib/JwksClient.js:94:16)
    at Request.self.callback (/usr/lib/realtime_notifications/node_modules/request/request.js:187:22)
    at Request.emit (events.js:98:17)
    at Request.<anonymous> (/usr/lib/realtime_notifications/node_modules/request/request.js:1048:10)
    at Request.emit (events.js:95:17)
    at IncomingMessage.<anonymous> (/usr/lib/realtime_notifications/node_modules/request/request.js:969:12)
    at IncomingMessage.emit (events.js:117:20)
    at _stream_readable.js:929:16

Create own JWKS

Hey there. I do not know where to put this, so I just will start here. Maybe there is a better place to discuss this then please give me a hint.

I want to mock the auth0 api for local testing. For this I would locally create a private key and use it to sign jwts. In my express or koa server, I would use the auth0 middleware for authentication. The middleware would try to get the jwks from the auth0 servers to verify the tokens in the headers of the requests. I would use nock to intercept these requests and inject my very own JWKS with the public key and cert for the private key I generated locally. With the fake reply the auth0 middleware should accept the locally created authentication token.

My problem is, that I do not find proper documentation on how to actually generate the JWKS from a private RSA key. I am kinda reverse engineering the JWKS that is provided from the JWKS.json entpoint but I think a quick example from auth0 would be very helpful. How about?

ExpressJwtSecret is not a function in Typescript Project

It seems as tho in the index.d.ts file then constructor "expressJwtSecret" has been capitalized to "ExpressJwtSecret" which will compile fine but the underlying js call will not generate anything since the js resources do not have any variable named ExpressJwtSecret. Fix would be to rename the variable in the declaration file.

Verification fails: (TypeScript) Option needs to be "aud" instead "audience"

Hello everyone,

I'm experiencing the issue that I need to pass "aud" instead "audience" as option for the client in order to get the token decripted.

We're using the latest available versions.

Given TS interface:

export function verify(
    token: string,
    secretOrPublicKey: string | Buffer | GetPublicKeyOrSecret,
    options?: VerifyOptions, // <---
    callback?: VerifyCallback,
): void;

export interface VerifyOptions {
    algorithms?: string[];
    audience?: string | RegExp | Array<string | RegExp>; // <---
    clockTimestamp?: number;
    clockTolerance?: number;
    issuer?: string | string[];
    ignoreExpiration?: boolean;
    ignoreNotBefore?: boolean;
    jwtid?: string;
    subject?: string;
    /**
     * @deprecated
     * Max age of token
     */
    maxAge?: string;
}

Verify call:

const options /*: VerifyOptions */ = {
  aud: config.AUTH0_AUDIENCE, // <---
  issuer: `https://${config.AUTH0_DOMAIN}/`,
  algorithms: ["RS256"],
};

const identity = new Promise((resolve, reject) => {
  jwt.verify(token, getKey, options, (err, decoded) => {
    if (err) {
      return reject(err);
    }
    resolve(decoded);
  });
});

TL;DR; Problem:

  • Interface defines "audience", failes
  • No interface, but option passed as "aud" succeeds

Thank you guys,
Daniel

handleSigningKeyError is being ignored

Here's my code:

jwks.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: '<my URI>',
    handleSigningKeyError: (err, cb) => {
      console.log('>>>>>>>>>>>>>', err)
      return cb(new Error('Authentication Error'));
    },
  })

The handleSigningKeyError is not being called.

When I call the API with an invalid token, it gives back:

UnauthorizedError: secret or public key must be provided
    at /home/henrique/labs/auth0/playground/node_modules/express-jwt/lib/index.js:102:22
    at /home/henrique/labs/auth0/playground/node_modules/jsonwebtoken/verify.js:27:18
    at process._tickCallback (internal/process/next_tick.js:150:11)

Support for other algorithms?

I'm currently looking for a library facilitating getting the keys from a JWKS endpoint. However, in our application we're using the ES256 algorithm for signing. I'm thus a little bit bummed to notice this library, which would seem to be a perfect fit for the problem I'm trying to solve, has a hard coded check on the key type.

I'm wondering:

  • as to why there's only support for the RSA algorithm
  • if there are plans to support other algorithms in the future
  • if you know any alternatives (after some extensive Googling, I have found none)
  • whether you would be open to a PR supporting other algorithms

Many thanks,
Thomas

passport typescript type conflict

Trying to use this package along with a custom passport strategy with express.

Issue is that this package includes the definitions from express-jwt, which are causing issues with projects that include both passport and node-jwks-rsa.

DefinitelyTyped/DefinitelyTyped#23976

Any recommendations to resolve this conflict of the Request.user type?

node_modules/@types/express-jwt/index.d.ts(43,13): error TS2717: Subsequent property declarations must have the same type.  Property 'user' must be of type 'User | undefined', but here has type 'any'.

koa example doesn't pass TS typechecker

I just tried the koa example (or at least an instantiation of almost exactly the same thing in my proiject), and I'm getting a TypeScript:

/nu/.links/skainswo/api/node_modules/ts-node/src/index.ts:261
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: โจฏ Unable to compile TypeScript:
src/server.ts(15,5): error TS2322: Type '(name: string, scheme: string, options?: any) => void' is not assignable to type 'string | string[] | Buffer | Buffer[] | SecretLoader'.
  Type '(name: string, scheme: string, options?: any) => void' is not assignable to type 'SecretLoader'.
    Type 'void' is not assignable to type 'Promise<string | string[] | Buffer | Buffer[]>'.
src/server.ts(25,3): error TS2554: Expected 2-4 arguments, but got 1.

    at createTSError (/nu/.links/skainswo/api/node_modules/ts-node/src/index.ts:261:12)
    at getOutput (/nu/.links/skainswo/api/node_modules/ts-node/src/index.ts:367:40)
    at Object.compile (/nu/.links/skainswo/api/node_modules/ts-node/src/index.ts:558:11)
    at Module.m._compile (/nu/.links/skainswo/api/node_modules/ts-node/src/index.ts:439:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:718:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/nu/.links/skainswo/api/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:605:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:544:12)
    at Function.Module._load (internal/modules/cjs/loader.js:536:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:760:12)

I have "jwks-rsa": "^1.3.0", "koa-jwt": "^3.5.1".

Dependency Request's sub dependency har-validator is causing install issues

The maintainer of har-validator unpublished v5.1.2.

ahmadnassri/node-har-validator#112

As it is widely used, this is causing installation issues across many packages.

While NPM users have figured workarounds Yarn users are not able to implement these same workarounds due to differences around unpublishing a package.

yarnpkg/yarn#6694

I'm not super familiar on the ins and outs of sub-dependencies, but it seems like this could be avoided by requiring the most recent 2.88 version of Request.

Thoughts?

Switch to prepare

When installing via git (npm install auth0/node-jwks-rsa), the package doesn't work, as the prePublish script is not being run. This could easily be fixed by changing the prePublish script to a prepare script, which does gets run by npm on a git install.

Basic usage doesn't work in TypeScript

The following code works according to the example code, and runs just fine but does not compile:

import * as jwksRsa from "jwks-rsa";

export function makeJwksClient(auth0Domain: string) {
  return jwksRsa({
    cache: true,
    jwksUri: `${auth0Domain}/.well-known/jwks.json`,
  });
}

TypeScript complains:

$ tsc --noEmit
../common/index.ts:5:10 - error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof JwksRsa' has no compatible call signatures.

5   return jwksRsa({
           ~~~~~~~~~
6     cache: true,
  ~~~~~~~~~~~~~~~~
7     jwksUri: `${auth0Domain}/.well-known/jwks.json`,
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8   });
  ~~~~

  ../common/index.ts:2:1
    2 import * as jwksRsa from "jwks-rsa";
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.


Found 1 error.

[NPM] version 1.5.1 is broken

Hi, I recently tried to use the latest version 1.5.1 in a TypeScript project and it seems like it's broken. In typescript, it doesn't resolve dependencies like express-jwt.

Also, if I try to download the package using npm pack jwks-rsa I got the following message:

npm notice === Tarball Details ===
npm notice name:          jwks-rsa
npm notice version:       1.5.1
npm notice filename:      jwks-rsa-1.5.1.tgz
npm notice package size:  2.8 MB
npm notice unpacked size: 10.6 MB
npm notice shasum:        05b7f1ba4e9829162e2aa3ab6a79d539416de200
npm notice integrity:     sha512-FcH0mrrfS/5CD[...]Pme4fb/ZoHKqQ==
npm notice total files:   2014
npm notice
jwks-rsa-1.5.1.tgz

Excluding examples from npm package

Hello Everyone,
when packaging my application to deploy with serverless, i noticed that the jwks-rsa was the biggest package, thanks to the "example" folders.
Is that folder needed in npm package? Taking it out would save 10MB (uncompressed)

Thanks!

@types/express-jwt included in dependencies

The @types/express-jwt package is added as a dependency, instead of devDependency. This is pulling a number of @types packages into our production build that shouldn't be necessary.

Promise Methods

Not to be curt, but it's 2019 folks. Callbacks are relics and Promise is the way forward. The last version of Node that doesn't support async/await out of the box is on its last leg and will soon drop out of LTS. Can we please get an updated version that doesn't solely rely on callbacks?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.