justinlettau / azure-ad-verify-token Goto Github PK
View Code? Open in Web Editor NEWVerify JWT issued by Azure Active Directory B2C.
License: MIT License
Verify JWT issued by Azure Active Directory B2C.
License: MIT License
As I currently cannot import the package in our nx based project because of Error [ERR_REQUIRE_ESM]: require() of ES Module not supported.
I wanted to use a dynamic import to load the package but it looks like it does not work neither.
const { verify } = import('azure-ad-verify-token');
console.log(verify) -> { default: {} }
Todo
dynamic import loads the package correctly
Todo
npm install azure-ad-verify-token
const { verify } = import('azure-ad-verify-token');
verify() -> verify is not a function
n/a
n/a
While updating to the version 3.0.2 ESM module start complaining about 'verify' method not importable. It is working fine in version 3.0.0
[2023-07-11T11:43:35.137Z] Worker was unable to load function testFun: 'Named export 'verify' not found. The requested module 'jsonwebtoken' is a CommonJS module, which may not support all module.exports as named exports.
[2023-07-11T11:43:35.137Z] CommonJS modules can always be imported via the default export, for example using:
[2023-07-11T11:43:35.137Z]
[2023-07-11T11:43:35.137Z] import pkg from 'jsonwebtoken';
[2023-07-11T11:43:35.137Z] const { decode: jwtDecode, verify: jwtVerify } = pkg;
[2023-07-11T11:43:35.137Z] '
[2023-07-11T11:43:35.138Z] Worker was unable to load function testFun: 'Named export 'verify' not found. The requested module 'jsonwebtoken' is a CommonJS module, which may not support all module.exports as named exports.
No issue in importing verify method and no build issue for 'jsonwebtoken'
n/a
tested in 3.0.2 where the error persist, downgrading to lower version 3.0.0 resolved the issue.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@types/jest
, jest
, ts-jest
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.github/workflows/ci.yml
actions/checkout v3
package.json
jsonwebtoken ^8.5.1
node-fetch ^2.6.5
rsa-pem-from-mod-exp ^0.8.4
@types/jest ^28.1.6
@types/jsonwebtoken ^8.5.5
@types/node-fetch ^2.5.12
@typescript-eslint/eslint-plugin ^5.30.6
@typescript-eslint/parser ^5.30.6
eslint ^8.19.0
eslint-config-prettier ^8.5.0
husky ^8.0.1
jest ^28.1.3
nock ^13.2.8
prettier ^2.7.1
pretty-quick ^3.1.3
standard-version ^9.5.0
ts-jest ^28.0.6
ts-node ^10.9.1
typescript ^4.7.4
node ^12.20.0 || ^14.13.1 || >=16.0.0
If two simultaneous requests use verify()
, the jwksUri
will be fetched twice.
It should only fetch once per jwksUri
.
await verify(a, config)
await verify(a, config)
Change the cache to Map<string, Promise>
and save the fetch Promise.
If the kid is not found then getPublicKey
never resolves. The current check introduced in #29 is not enough since the call to setDeferredItem
before implies that even if the kid is not found the cache will contain an empty promise that will never resolve.
Hello,
I am getting this error:
Worker was unable to load function etdoUploadFunc: 'require() of ES Module C:\projects\node_modules\azure-ad-verify-token\dist\index.js from C:\projects\api\dist\api\authMiddleware.js not supported. Instead change the require of index.js in C:\projects\api\dist\api\authMiddleware.js to a dynamic import() which is available in all CommonJS modules.'
but I am using import { verify, VerifyOptions } from 'azure-ad-verify-token';
version: "azure-ad-verify-token": "^3.0.1"
I also tried const { verify } = await import('azure-ad-verify-token');
but I am getting this error Result: Failure Exception: require() of ES Module
Invalid tokens might be null:
https://github.com/auth0/node-jsonwebtoken/blob/5f10bf9957a2541828501cfecab0310908b2f62f/decode.js#L6
That is why this code throws Cannot read property 'header' of null
azure-ad-verify-token/src/verify.ts
Lines 54 to 55 in b0fbe8c
Instead, it would make sense to throw an 'invalid token'
error like here:
https://github.com/auth0/node-jsonwebtoken/blob/5f10bf9957a2541828501cfecab0310908b2f62f/verify.js#L75
I am facing issue in verifying my oauth ID token.
When i use the id token obtain from the aad_oauth flutter , i am facing a error "JWTVerification:: Error JsonWebTokenError: invalid signature". Do you know what is the id token failed the check?
When i use jwt.ms, everything look likes it is in order.
Currently the public key cache value is set when the value is fetched and subsequent calls that need the public keys will get the cached version. Unless I missed something in the code, the cached value does not expire.
For short running applications this is not a problem.
But for long running applications like a rest-api this could be a problem once the keys in Azure are rotated and the application has not restarted.
Change the current Map<string, string> to a Map<string, object> where the object contains both an expiry value which should be a timestamp as well as the string.
When the value is initially populated set the expiry value to a timestamp in the future - e.g. expiry = new Date().getTime() + cacheLifeTimeMs
where cacheLifeTimeMs is the allowed life time of the cached value in ms. The cacheLifeTimeMs could be a configurable value - and maybe default to a 1 hour life time if not configured.
On subsequent get calls to the cache, the cached value is ok if expiry > new Date().getTime()
- otherwise it should be deleted, and a new fresh value should be fetched and cached.
n/a
I will be happy to make a PR if such are accepted?
What kind of issue is this?
[x ] Bug report.
[ ] Feature request.
No matter how I try this script (vanilla node.js or typescript) I cannot run verify b/c of module issues.
When running as ts-node, I get:
require() of ES Module ...node_modules/azure-ad-verify-token/dist/index.js from index.ts not supported.
to a dynamic import() which is available in all CommonJS modules.
when running in javascript
Cannot find module azure-ad-verify-token/dist/config' imported from ../node_modules/azure-ad-verify-token/dist/index.js
Todo
Try to use the library as illustrated
n/a
n/a
When verifying tokens the JWT library which is used in this project support issuer as a string or an array of strings. To align this project with that I suggest allowing issuer as a string or an array of strings. This functionality comes in handy in cases where we setup azure b2c custom domains in this scenario both the default azure domain and the custom domain should be regarded as valid issuers.
After taking a look at the code it looks like the change should be simple enough and I'm happy to push a pull request. Essentially we just need to change VerifyOptions interface to look like below.
export interface VerifyOptions {
...
issuer: string | string[];
...
}
n/a
I'm facing a similar problem that was described in issue#45. In my nestjs
project, I can import verify
function from the package without any typescript warnings, but the compilation fails with following message:
Error [ERR_REQUIRE_ESM]: require() of ES Module ...\node_modules\azure-ad-verify-token\dist\index.js from ...\my-project-file.js not supported.
Instead change the require of index.js in ...\my-project-file.js to a dynamic import() which is available in all CommonJS modules.
Using a dynamic import would be a bit annoying as I cannot use top-level await due to standard nestjs
project configuration, which I'm not allowed to alter easily.
When I try dynamic import in a function (with regards to the advice from issue#47), the code compiles. However, strange enough, when the function with dynamic import runs, the app crashes with the very same error message - including the "change to a dynamic import()" hint.
I can import verify
function from the package and use it without any compilation errors or application crashes.
I'm trying to use the package (version 3.0.0
, but downgrading to 2.0.1
doesn't help) in a standard nestjs
project generated from Nest CLI.
From project's package.json
:
...
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.2.0",
"@nestjs/core": "^9.0.0",
"@nestjs/mongoose": "^9.2.1",
"@nestjs/platform-express": "^9.0.0",
"azure-ad-verify-token": "^3.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"cookie-session": "^2.0.0",
"mongoose": "^6.7.3",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
},
"devDependencies": {
...
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.0",
"typescript": "^4.7.4"
}
...
Here's my tsconfig.json
:
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
The code looks like so:
import {verify, VerifyOptions} from 'azure-ad-verify-token';
// other imports
const options: VerifyOptions = {
jwksUri: 'https://my-jwksUri',
issuer: 'https://my-issuer',
audience: 'my-audience'
};
@Injectable()
export class CurrentUserMiddleware implements NestMiddleware {
constructor(private usersService: UsersService) {}
async use(req: Request, res: Response, next: NextFunction) {
const token = req.headers['authorization'];
try {
const resolved = await verify(token, options);
console.log(resolved);
} catch (err) {
console.log('azure-ad-verify-token/verify FAILED');
console.log(err);
}
// some more code
}
}
When verifying a token provided by AzureAD that is from the v2.0 endpoint, a nonce is included. That nonce is actually SHA-256'd before the signature is calculated, but the non-SHA'd version is sent along in the token. Therefore, the signature will fail to verify without fixing the nonce prior to verification.
The signature would verify
As a quick fix, I'm using the following code to fix the nonce prior to calling the verify function:
const SHA2 = require("sha2");
const base64url = require('base64url');
const { verify } = require('azure-ad-verify-token');
const doVerify = (token, options) => {
const [header_raw, body_raw, sig] = token.split('.');
const header_decoded = JSON.parse(base64url.decode(header_raw));
header_decoded.nonce = base64url.encode(SHA2["SHA-256"](header_decoded.nonce));
const new_header_raw = base64url.encode(JSON.stringify(header_decoded));
const new_token = `${new_header_raw}.${body_raw}.${sig}`;
return verify(new_token, options);
};
When I try to validate a token which is not signed with any of the key-id's which are available in the jwksUri, then the library gets completly stuck, because the cached promise will never resolve nor reject.
In my case we have support for multiple IDPs and the token to validate was from another IDP as the jwksUri points to.
To solve this, the logic for fetching from the jwksUri and caching public keys by key-id need to be changed.
The library should return that the token is invalid or should return that for the key-id of the token, there was no PublicKey found.
The library should not return an ever-pending promise.
Try to validate a token which is from another IDP than the jwksUri.
In theory, the current implementation of verify.ts should also have the issue, that, if there is a network problem and fetching the jwksUri fails, there will be an ever-pending promise in the cache which then leads to a similar issue that the lib gets completly stuck. But this case I have not explicitly tested.
npm audit
and dependabots report two high-severity issues:
# npm audit report
json5 2.0.0 - 2.2.1
Severity: high
Prototype Pollution in JSON5 via Parse Method - https://github.com/advisories/GHSA-9c47-m6qq-7p4h
fix available via `npm audit fix`
node_modules/json5
jsonwebtoken <=8.5.1
Severity: high
jsonwebtoken vulnerable to signature validation bypass due to insecure default algorithm in jwt.verify() - https://github.com/advisories/GHSA-qwph-4952-7xr6
jsonwebtoken has insecure input validation in jwt.verify function - https://github.com/advisories/GHSA-27h2-hvpr-p74q
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/jsonwebtoken
2 high severity vulnerabilities
To address issues that do not require attention, run:
npm audit fix
To address all issues (including breaking changes), run:
npm audit fix --force
Todo
by applying the --fix
es
Consumers would not be polluted by audit reports, this package would be more secure and npm audit
would be fixed.
npm i && npm audit
Implement a way to informe a proxyAgent instance or proxy configurations to the node-fetch to aplications running behinden enterprise proxy;
Somenting like msal-node Configuration.system.networkClient
https://azuread.github.io/microsoft-authentication-library-for-js/ref/types/_azure_msal_node.NodeSystemOptions.html#__type.networkClient
INetworkModule example (usede in SAML)
import type { INetworkModule, NetworkRequestOptions, NetworkResponse } from "@azure/msal-node";
import { HttpsProxyAgent } from "https-proxy-agent";
import fetch from 'node-fetch';
const proxyUrl = process.env['HTTPS_PROXY'] || process.env['HTTP_PROXY'];
if (!proxyUrl) {
throw new Error('Missing HTTP/S_PROXY env');
}
export const proxyAgent = new HttpsProxyAgent(proxyUrl);
export class CustomHttpClient implements INetworkModule {
sendGetRequestAsync<T>(url: string, options?: NetworkRequestOptions): Promise<NetworkResponse<T>> {
return this.sendRequestAsync(url, 'GET', options);
}
sendPostRequestAsync<T>(url: string, options?: NetworkRequestOptions): Promise<NetworkResponse<T>> {
return this.sendRequestAsync(url, 'POST', options);
}
private async sendRequestAsync<T>(
url: string,
method: 'GET' | 'POST',
options: NetworkRequestOptions = {},
): Promise<NetworkResponse<T>> {
try {
const requestOptions = {
method: method,
headers: options.headers,
body: method === 'POST' ? options.body : undefined,
agent: proxyAgent,
};
console.log('>>> url', url, requestOptions);
const response = await fetch(url, requestOptions);
const data = await response.json() as any;
const headersObj: Record<string, string> = {};
response.headers.forEach((value, key) => {
headersObj[key] = value;
});
return {
headers: headersObj,
body: data,
status: response.status,
};
} catch (err) {
console.error('CustomRequest', err);
throw new Error('Custom request error');
}
}
}
What kind of issue is this?
[ V] Bug report.
[ ] Feature request.
the solution of latest PR(#48) not working, as 'done' was set as resolve function, so !item.done won't help to validate if the item is empty. Maybe need to rethink if do you really need to set done as promise in setDeferredItem
Todo
pass a jwt which kid not in public key page of Azure AD
n/a
n/a
While trying to use this package in NextJS on server-side, error is thrown about jwt imports inside the package.
error file:///Users/tomas/projects/foo/node_modules/azure-ad-verify-token/dist/verify.js:1
import { decode as jwtDecode, verify as jwtVerify } from 'jsonwebtoken';
^^^^^^
SyntaxError: Named export 'decode' not found. The requested module 'jsonwebtoken' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'jsonwebtoken';
const { decode: jwtDecode, verify: jwtVerify } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:123:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:189:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:438:15) {
digest: undefined
}
Changes to imports have been introduced in #56
I have installed 3.0.1 and it works fine.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.