passport-entra 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/passport-entra.d.ts +32 -14
- package/dist/passport-entra.js +10 -1
- package/package.json +2 -1
- package/passport-entra.ts +35 -22
package/dist/passport-entra.d.ts
CHANGED
|
@@ -1,39 +1,57 @@
|
|
|
1
1
|
import { Strategy } from 'passport';
|
|
2
2
|
import { createRemoteJWKSet } from 'jose';
|
|
3
3
|
import type { Request } from 'express';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Bearerstrategy options
|
|
6
|
+
*/
|
|
7
|
+
export interface BearerOptions {
|
|
8
|
+
/** If set, check aud claim against this audience */
|
|
5
9
|
audience?: string | string[];
|
|
10
|
+
/** ClientID of app in Entra, check aud claim against clientID if audience options is not set */
|
|
6
11
|
clientID: string;
|
|
12
|
+
/** clockSkew allowed when checking nbf and exp claims */
|
|
7
13
|
clockSkew?: string | number;
|
|
14
|
+
/** well known oid-configuration endpoint, ie <issuer>/.well-known/openid-configuration */
|
|
8
15
|
identityMetadata: string;
|
|
16
|
+
/** iss claim check, ie https://login.microsoftonline.com/<tenantID>/v2.0 - tenantID of app in Entra */
|
|
9
17
|
issuer: string | string[];
|
|
18
|
+
/** scp claim check */
|
|
10
19
|
scope?: string[];
|
|
11
20
|
}
|
|
12
|
-
|
|
13
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Called by this BearerStrategy when the token has been validated.
|
|
23
|
+
* Use the token (the bearer JWT payload) to find the user. Then call done.
|
|
24
|
+
*/
|
|
25
|
+
export type VerifyCallback = (token: object, done: VerifyCompleteCallback) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Call this in the VerifyCallback with either the found user or an error.
|
|
28
|
+
* The user ends up in req.user, the info in req.authInfo.
|
|
29
|
+
* An error results in an authentication failure. Status is ignored.
|
|
30
|
+
*/
|
|
31
|
+
export type VerifyCompleteCallback = (err: unknown, user?: Express.User | false | null, info?: object, status?: number | number[]) => void;
|
|
14
32
|
/**
|
|
15
33
|
* Bearerstrategy for password.js, used with Microsoft Entra as identity provider
|
|
16
34
|
*/
|
|
17
35
|
export default class BearerStrategy extends Strategy {
|
|
18
|
-
/** aud claim check */
|
|
19
36
|
audience: string[];
|
|
20
|
-
/** clientID to check */
|
|
21
37
|
clientID: string;
|
|
22
|
-
/** clockSkew allowed when checking nbf and exp */
|
|
23
38
|
clockSkew: string | number;
|
|
24
|
-
/** well known oid-configuration endpoint */
|
|
25
39
|
identityMetadata: string;
|
|
26
|
-
/** iss claim check */
|
|
27
40
|
issuer: string | string[];
|
|
28
|
-
/** strategy name */
|
|
29
41
|
name: string;
|
|
30
|
-
/** scp claim check */
|
|
31
42
|
scope: string[];
|
|
32
|
-
/** call this function to get the user belonging to the token */
|
|
33
43
|
verifyFn: VerifyCallback;
|
|
34
|
-
/** cached JWK set from well known oid-configuration endpoint */
|
|
35
44
|
jwks: ReturnType<typeof createRemoteJWKSet> | undefined;
|
|
36
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new BearerStrategy instance.
|
|
47
|
+
* @param options The validation options.
|
|
48
|
+
* @param verifyFn Called when a token is validated, needs to provide the User object.
|
|
49
|
+
*/
|
|
50
|
+
constructor(options: BearerOptions, verifyFn: VerifyCallback);
|
|
51
|
+
/**
|
|
52
|
+
* Validates the Bearer token in a request.
|
|
53
|
+
* When validated, calls VerifyFn to retrieve the User belonging to the token.
|
|
54
|
+
* @param req The Express request
|
|
55
|
+
*/
|
|
37
56
|
authenticate(req: Request): Promise<void>;
|
|
38
57
|
}
|
|
39
|
-
export {};
|
package/dist/passport-entra.js
CHANGED
|
@@ -15,10 +15,14 @@ const jose_1 = require("jose");
|
|
|
15
15
|
* Bearerstrategy for password.js, used with Microsoft Entra as identity provider
|
|
16
16
|
*/
|
|
17
17
|
class BearerStrategy extends passport_1.Strategy {
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new BearerStrategy instance.
|
|
20
|
+
* @param options The validation options.
|
|
21
|
+
* @param verifyFn Called when a token is validated, needs to provide the User object.
|
|
22
|
+
*/
|
|
18
23
|
constructor(options, verifyFn) {
|
|
19
24
|
var _a, _b, _c;
|
|
20
25
|
super();
|
|
21
|
-
/** strategy name */
|
|
22
26
|
this.name = 'oauth-bearer';
|
|
23
27
|
this.verifyFn = verifyFn;
|
|
24
28
|
let audience = (_a = options.audience) !== null && _a !== void 0 ? _a : options.clientID;
|
|
@@ -32,6 +36,11 @@ class BearerStrategy extends passport_1.Strategy {
|
|
|
32
36
|
this.issuer = options.issuer;
|
|
33
37
|
this.scope = (_c = options.scope) !== null && _c !== void 0 ? _c : [];
|
|
34
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Validates the Bearer token in a request.
|
|
41
|
+
* When validated, calls VerifyFn to retrieve the User belonging to the token.
|
|
42
|
+
* @param req The Express request
|
|
43
|
+
*/
|
|
35
44
|
authenticate(req) {
|
|
36
45
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
46
|
var _a;
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "passport-entra",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Microft Entra authentication strategy for passport",
|
|
5
5
|
"main": "dist/passport-entra.js",
|
|
6
6
|
"types": "dist/passport-entra.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
8
9
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
10
|
},
|
|
10
11
|
"author": "Jan Bakker",
|
package/passport-entra.ts
CHANGED
|
@@ -3,18 +3,36 @@ import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
|
3
3
|
|
|
4
4
|
import type { Request } from 'express';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Bearerstrategy options
|
|
8
|
+
*/
|
|
9
|
+
export interface BearerOptions {
|
|
10
|
+
/** If set, check aud claim against this audience */
|
|
7
11
|
audience?: string | string[];
|
|
12
|
+
/** ClientID of app in Entra, check aud claim against clientID if audience options is not set */
|
|
8
13
|
clientID: string;
|
|
14
|
+
/** clockSkew allowed when checking nbf and exp claims */
|
|
9
15
|
clockSkew?: string | number;
|
|
16
|
+
/** well known oid-configuration endpoint, ie <issuer>/.well-known/openid-configuration */
|
|
10
17
|
identityMetadata: string;
|
|
18
|
+
/** iss claim check, ie https://login.microsoftonline.com/<tenantID>/v2.0 - tenantID of app in Entra */
|
|
11
19
|
issuer: string | string[];
|
|
20
|
+
/** scp claim check */
|
|
12
21
|
scope?: string[];
|
|
13
22
|
}
|
|
14
23
|
|
|
15
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Called by this BearerStrategy when the token has been validated.
|
|
26
|
+
* Use the token (the bearer JWT payload) to find the user. Then call done.
|
|
27
|
+
*/
|
|
28
|
+
export type VerifyCallback = (token: object, done: VerifyCompleteCallback) => void;
|
|
16
29
|
|
|
17
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Call this in the VerifyCallback with either the found user or an error.
|
|
32
|
+
* The user ends up in req.user, the info in req.authInfo.
|
|
33
|
+
* An error results in an authentication failure. Status is ignored.
|
|
34
|
+
*/
|
|
35
|
+
export type VerifyCompleteCallback = (
|
|
18
36
|
err: unknown,
|
|
19
37
|
user?: Express.User | false | null,
|
|
20
38
|
info?: object,
|
|
@@ -25,34 +43,22 @@ export type AuthenticateCallback = (
|
|
|
25
43
|
* Bearerstrategy for password.js, used with Microsoft Entra as identity provider
|
|
26
44
|
*/
|
|
27
45
|
export default class BearerStrategy extends Strategy {
|
|
28
|
-
/** aud claim check */
|
|
29
46
|
audience;
|
|
30
|
-
|
|
31
|
-
/** clientID to check */
|
|
32
47
|
clientID;
|
|
33
|
-
|
|
34
|
-
/** clockSkew allowed when checking nbf and exp */
|
|
35
48
|
clockSkew;
|
|
36
|
-
|
|
37
|
-
/** well known oid-configuration endpoint */
|
|
38
|
-
identityMetadata: string;
|
|
39
|
-
|
|
40
|
-
/** iss claim check */
|
|
49
|
+
identityMetadata;
|
|
41
50
|
issuer;
|
|
42
|
-
|
|
43
|
-
/** strategy name */
|
|
44
51
|
name = 'oauth-bearer';
|
|
45
|
-
|
|
46
|
-
/** scp claim check */
|
|
47
52
|
scope;
|
|
48
|
-
|
|
49
|
-
/** call this function to get the user belonging to the token */
|
|
50
53
|
verifyFn;
|
|
51
|
-
|
|
52
|
-
/** cached JWK set from well known oid-configuration endpoint */
|
|
53
54
|
jwks: ReturnType<typeof createRemoteJWKSet> | undefined;
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Creates a new BearerStrategy instance.
|
|
58
|
+
* @param options The validation options.
|
|
59
|
+
* @param verifyFn Called when a token is validated, needs to provide the User object.
|
|
60
|
+
*/
|
|
61
|
+
constructor(options: BearerOptions, verifyFn: VerifyCallback) {
|
|
56
62
|
super();
|
|
57
63
|
|
|
58
64
|
this.verifyFn = verifyFn;
|
|
@@ -70,6 +76,11 @@ export default class BearerStrategy extends Strategy {
|
|
|
70
76
|
this.scope = options.scope ?? [];
|
|
71
77
|
}
|
|
72
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Validates the Bearer token in a request.
|
|
81
|
+
* When validated, calls VerifyFn to retrieve the User belonging to the token.
|
|
82
|
+
* @param req The Express request
|
|
83
|
+
*/
|
|
73
84
|
async authenticate(req: Request) {
|
|
74
85
|
try {
|
|
75
86
|
if (!this.jwks) {
|
|
@@ -81,12 +92,14 @@ export default class BearerStrategy extends Strategy {
|
|
|
81
92
|
const { jwks_uri } = await res.json() as { jwks_uri: string };
|
|
82
93
|
this.jwks = createRemoteJWKSet(new URL(jwks_uri));
|
|
83
94
|
}
|
|
95
|
+
|
|
84
96
|
const header = req.get('authorization');
|
|
85
97
|
const headerParts = header?.split(' ');
|
|
86
98
|
const jwt = headerParts?.length === 2 && headerParts[0].toLowerCase() === 'bearer' && headerParts[1];
|
|
87
99
|
if (!jwt) {
|
|
88
100
|
throw new Error('Unable to extract Bearer token from Authorization header');
|
|
89
101
|
}
|
|
102
|
+
|
|
90
103
|
const { payload } = await jwtVerify(jwt, this.jwks, {
|
|
91
104
|
audience: this.audience, // aud
|
|
92
105
|
clockTolerance: this.clockSkew, // exp, nbf
|