@azure/identity-cache-persistence 1.1.2-alpha.20240917.2 → 1.1.2-alpha.20240927.1
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/README.md +15 -34
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist-esm/identity/src/credentials/chainedTokenCredential.js +8 -1
- package/dist-esm/identity/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/identity/src/credentials/credentialPersistenceOptions.js.map +1 -1
- package/dist-esm/identity/src/credentials/deviceCodeCredential.js +6 -4
- package/dist-esm/identity/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/identity/src/credentials/onBehalfOfCredential.js.map +1 -1
- package/dist-esm/identity/src/plugins/consumer.js +6 -8
- package/dist-esm/identity/src/plugins/consumer.js.map +1 -1
- package/dist-esm/identity/src/tokenProvider.js +3 -3
- package/dist-esm/identity/src/tokenProvider.js.map +1 -1
- package/dist-esm/identity-cache-persistence/src/index.js +8 -8
- package/dist-esm/identity-cache-persistence/src/index.js.map +1 -1
- package/package.json +14 -13
- package/types/identity-cache-persistence.d.ts +8 -8
package/README.md
CHANGED
|
@@ -6,13 +6,6 @@ This package provides a plugin to the Azure Identity library for JavaScript ([`@
|
|
|
6
6
|
|
|
7
7
|
## Getting started
|
|
8
8
|
|
|
9
|
-
```javascript
|
|
10
|
-
const { useIdentityPlugin } = require("@azure/identity");
|
|
11
|
-
const { cachePersistencePlugin } = require("@azure/identity-cache-persistence");
|
|
12
|
-
|
|
13
|
-
useIdentityPlugin(cachePersistencePlugin);
|
|
14
|
-
```
|
|
15
|
-
|
|
16
9
|
### Prerequisites
|
|
17
10
|
|
|
18
11
|
- An [Azure subscription](https://azure.microsoft.com/free/).
|
|
@@ -38,9 +31,9 @@ If this is your first time using `@azure/identity` or Microsoft Entra ID, we rec
|
|
|
38
31
|
|
|
39
32
|
As of `@azure/identity` version 2.0.0, the Identity client library for JavaScript includes a plugin API. This package (`@azure/identity-cache-persistence`) exports a plugin object that you must pass as an argument to the top-level `useIdentityPlugin` function from the `@azure/identity` package. Enable token cache persistence in your program as follows:
|
|
40
33
|
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
```ts snippet:getting_started
|
|
35
|
+
import { useIdentityPlugin } from "@azure/identity";
|
|
36
|
+
import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
|
|
44
37
|
|
|
45
38
|
useIdentityPlugin(cachePersistencePlugin);
|
|
46
39
|
```
|
|
@@ -51,30 +44,18 @@ After calling `useIdentityPlugin`, the persistent token cache plugin is register
|
|
|
51
44
|
|
|
52
45
|
Once the plugin is registered, you can enable token cache persistence by passing `tokenCachePersistenceOptions` with an `enabled` property set to `true` to a credential constructor. In the following example, we use the `DeviceCodeCredential`, since persistent caching of its tokens allows you to skip the interactive device-code authentication flow if a cached token is available.
|
|
53
46
|
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
const { cachePersistencePlugin } = require("@azure/identity-cache-persistence");
|
|
57
|
-
|
|
58
|
-
useIdentityPlugin(cachePersistencePlugin);
|
|
59
|
-
|
|
60
|
-
async function main() {
|
|
61
|
-
const credential = new DeviceCodeCredential({
|
|
62
|
-
tokenCachePersistenceOptions: {
|
|
63
|
-
enabled: true,
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// We'll use the Microsoft Graph scope as an example
|
|
68
|
-
const scope = "https://graph.microsoft.com/.default";
|
|
69
|
-
|
|
70
|
-
// Print out part of the access token
|
|
71
|
-
console.log((await credential.getToken(scope)).token.substr(0, 10), "...");
|
|
72
|
-
}
|
|
47
|
+
```ts snippet:device_code_credential_example
|
|
48
|
+
import { DeviceCodeCredential } from "@azure/identity";
|
|
73
49
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
50
|
+
const credential = new DeviceCodeCredential({
|
|
51
|
+
tokenCachePersistenceOptions: {
|
|
52
|
+
enabled: true,
|
|
53
|
+
},
|
|
77
54
|
});
|
|
55
|
+
// We'll use the Microsoft Graph scope as an example
|
|
56
|
+
const scope = "https://graph.microsoft.com/.default";
|
|
57
|
+
// Print out part of the access token
|
|
58
|
+
console.log((await credential.getToken(scope)).token.substring(0, 10), "...");
|
|
78
59
|
```
|
|
79
60
|
|
|
80
61
|
## Troubleshooting
|
|
@@ -83,8 +64,8 @@ main().catch((error) => {
|
|
|
83
64
|
|
|
84
65
|
Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`:
|
|
85
66
|
|
|
86
|
-
```
|
|
87
|
-
|
|
67
|
+
```ts snippet:logging
|
|
68
|
+
import { setLogLevel } from "@azure/logger";
|
|
88
69
|
|
|
89
70
|
setLogLevel("info");
|
|
90
71
|
```
|
package/dist/index.js
CHANGED
|
@@ -171,18 +171,18 @@ function createPersistenceCachePlugin(options) {
|
|
|
171
171
|
*
|
|
172
172
|
* Example:
|
|
173
173
|
*
|
|
174
|
-
* ```
|
|
175
|
-
* import {
|
|
176
|
-
* import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
|
|
177
|
-
*
|
|
178
|
-
* // Load the plugin
|
|
179
|
-
* useIdentityPlugin(cachePersistencePlugin);
|
|
174
|
+
* ```ts snippet:device_code_credential_example
|
|
175
|
+
* import { DeviceCodeCredential } from "@azure/identity";
|
|
180
176
|
*
|
|
181
177
|
* const credential = new DeviceCodeCredential({
|
|
182
178
|
* tokenCachePersistenceOptions: {
|
|
183
|
-
* enabled: true
|
|
184
|
-
* }
|
|
179
|
+
* enabled: true,
|
|
180
|
+
* },
|
|
185
181
|
* });
|
|
182
|
+
* // We'll use the Microsoft Graph scope as an example
|
|
183
|
+
* const scope = "https://graph.microsoft.com/.default";
|
|
184
|
+
* // Print out part of the access token
|
|
185
|
+
* console.log((await credential.getToken(scope)).token.substring(0, 10), "...");
|
|
186
186
|
* ```
|
|
187
187
|
*/
|
|
188
188
|
const cachePersistencePlugin = (context) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/platforms.ts","../src/provider.ts","../src/index.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* eslint-disable tsdoc/syntax */\n\nimport * as path from \"path\";\nimport {\n DataProtectionScope,\n FilePersistence,\n FilePersistenceWithDataProtection,\n KeychainPersistence,\n LibSecretPersistence,\n IPersistence as Persistence,\n} from \"@azure/msal-node-extensions\";\nimport { TokenCachePersistenceOptions } from \"@azure/identity\";\n\n/**\n * Local application data folder\n * Expected values:\n * - Darwin: '/Users/user/'\n * - Windows 8+: 'C:\\Users\\user\\AppData\\Local'\n * - Linux: '/home/user/.local/share'\n * @internal\n */\nconst localApplicationDataFolder =\n process.env.APPDATA?.replace?.(/(.Roaming)*$/, \"\\\\Local\") ?? process.env.HOME!;\n\n/**\n * Dictionary of values that we use as default as we discover, pick and enable the persistence layer.\n * @internal\n */\nexport const defaultMsalValues = {\n tokenCache: {\n name: \"msal.cache\",\n // Expected values:\n // - Darwin: '/Users/user/.IdentityService'\n // - Windows 8+: 'C:\\Users\\user\\AppData\\Local\\.IdentityService'\n // - Linux: '/home/user/.IdentityService'\n directory: path.join(localApplicationDataFolder, \".IdentityService\"),\n },\n keyRing: {\n label: \"MSALCache\",\n schema: \"msal.cache\",\n collection: \"default\",\n attributes: {\n MsalClientID: \"Microsoft.Developer.IdentityService\",\n \"Microsoft.Developer.IdentityService\": \"1.0.0.0\",\n },\n service: \"Microsoft.Developer.IdentityService\",\n account: \"MSALCache\",\n },\n keyChain: {\n service: \"Microsoft.Developer.IdentityService\",\n account: \"MSALCache\",\n },\n};\n\n/**\n * Options that are used by the underlying MSAL cache provider.\n * @internal\n */\nexport type MsalPersistenceOptions = Omit<TokenCachePersistenceOptions, \"enabled\">;\n\n/**\n * A function that returns a persistent token cache instance.\n * @internal\n */\ntype MsalPersistenceFactory = (options?: MsalPersistenceOptions) => Promise<Persistence>;\n\n/**\n * Expected responses:\n * - Darwin: '/Users/user/.IdentityService/<name>'\n * - Windows 8+: 'C:\\Users\\user\\AppData\\Local\\.IdentityService\\<name>'\n * - Linux: '/home/user/.IdentityService/<name>'\n * @internal\n */\nfunction getPersistencePath(name: string): string {\n return path.join(defaultMsalValues.tokenCache.directory, name);\n}\n\n/**\n * Set of the platforms we attempt to deliver persistence on.\n *\n * - On Windows we use DPAPI.\n * - On OSX (Darwin), we try to use the system's Keychain, otherwise if the property `unsafeAllowUnencryptedStorage` is set to true, we use an unencrypted file.\n * - On Linux, we try to use the system's Keyring, otherwise if the property `unsafeAllowUnencryptedStorage` is set to true, we use an unencrypted file.\n *\n * Other platforms _are not supported_ at this time.\n *\n * @internal\n */\nexport const msalPersistencePlatforms: Partial<Record<NodeJS.Platform, MsalPersistenceFactory>> = {\n win32: ({ name = defaultMsalValues.tokenCache.name } = {}): Promise<Persistence> =>\n FilePersistenceWithDataProtection.create(\n getPersistencePath(name),\n DataProtectionScope.CurrentUser,\n ),\n\n darwin: async (options: MsalPersistenceOptions = {}): Promise<Persistence> => {\n const { name, unsafeAllowUnencryptedStorage } = options;\n const { service, account } = defaultMsalValues.keyChain;\n const persistencePath = getPersistencePath(name || defaultMsalValues.tokenCache.name);\n\n try {\n const persistence = await KeychainPersistence.create(persistencePath, service, account);\n // If we don't encounter an error when trying to read from the keychain, then we should be good to go.\n await persistence.load();\n return persistence;\n } catch (e: any) {\n // If we got an error while trying to read from the keyring,\n // we will proceed only if the user has specified that unencrypted storage is allowed.\n if (!unsafeAllowUnencryptedStorage) {\n throw new Error(\"Unable to read from the macOS Keychain.\");\n }\n return FilePersistence.create(persistencePath);\n }\n },\n\n linux: async (options: MsalPersistenceOptions = {}): Promise<Persistence> => {\n const { name, unsafeAllowUnencryptedStorage } = options;\n const { service, account } = defaultMsalValues.keyRing;\n const persistencePath = getPersistencePath(name || defaultMsalValues.tokenCache.name);\n\n try {\n const persistence = await LibSecretPersistence.create(persistencePath, service, account);\n // If we don't encounter an error when trying to read from the keyring, then we should be good to go.\n await persistence.load();\n return persistence;\n } catch (e: any) {\n // If we got an error while trying to read from the keyring,\n // we will proceed only if the user has specified that unencrypted storage is allowed.\n if (!unsafeAllowUnencryptedStorage) {\n throw new Error(\"Unable to read from the system keyring (libsecret).\");\n }\n return FilePersistence.create(persistencePath);\n }\n },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { MsalPersistenceOptions, msalPersistencePlatforms } from \"./platforms\";\nimport { IPersistence as Persistence, PersistenceCachePlugin } from \"@azure/msal-node-extensions\";\nimport { ICachePlugin as CachePlugin } from \"@azure/msal-node\";\n\n/**\n * This is used to gain access to the underlying Persistence instance, which we use for testing\n *\n * @returns a raw persistence instance\n * @internal\n */\nexport async function createPersistence(options: MsalPersistenceOptions): Promise<Persistence> {\n const persistence = await msalPersistencePlatforms[process.platform]?.(options);\n\n if (persistence === undefined) {\n throw new Error(\"no persistence providers are available on this platform\");\n }\n\n return persistence;\n}\n\nexport async function createPersistenceCachePlugin(\n options?: MsalPersistenceOptions,\n): Promise<CachePlugin> {\n const persistence = await createPersistence(options ?? {});\n\n return new PersistenceCachePlugin(persistence, {\n retryNumber: 100,\n retryDelay: 50,\n });\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzurePluginContext } from \"../../identity/src/plugins/provider\";\nimport { IdentityPlugin } from \"@azure/identity\";\nimport { createPersistenceCachePlugin } from \"./provider\";\n\n/**\n * A plugin that provides persistent token caching for `@azure/identity`\n * credentials. The plugin API is compatible with `@azure/identity` versions\n * 2.0.0 and later. Load this plugin using the `useIdentityPlugin`\n * function, imported from `@azure/identity`.\n *\n * In order to enable this functionality, you must also pass\n * `tokenCachePersistenceOptions` to your credential constructors with an\n * `enabled` property set to true.\n *\n * Example:\n *\n * ```javascript\n * import { useIdentityPlugin, DeviceCodeCredential } from \"@azure/identity\";\n * import { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\n *\n * // Load the plugin\n * useIdentityPlugin(cachePersistencePlugin);\n *\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true\n * }\n * });\n * ```\n */\n\nexport const cachePersistencePlugin: IdentityPlugin = (context) => {\n const { cachePluginControl } = context as AzurePluginContext;\n\n cachePluginControl.setPersistence(createPersistenceCachePlugin);\n};\n"],"names":["path","FilePersistenceWithDataProtection","DataProtectionScope","__awaiter","KeychainPersistence","FilePersistence","LibSecretPersistence","PersistenceCachePlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/platforms.ts","../src/provider.ts","../src/index.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* eslint-disable tsdoc/syntax */\n\nimport * as path from \"path\";\nimport {\n DataProtectionScope,\n FilePersistence,\n FilePersistenceWithDataProtection,\n KeychainPersistence,\n LibSecretPersistence,\n IPersistence as Persistence,\n} from \"@azure/msal-node-extensions\";\nimport { TokenCachePersistenceOptions } from \"@azure/identity\";\n\n/**\n * Local application data folder\n * Expected values:\n * - Darwin: '/Users/user/'\n * - Windows 8+: 'C:\\Users\\user\\AppData\\Local'\n * - Linux: '/home/user/.local/share'\n * @internal\n */\nconst localApplicationDataFolder =\n process.env.APPDATA?.replace?.(/(.Roaming)*$/, \"\\\\Local\") ?? process.env.HOME!;\n\n/**\n * Dictionary of values that we use as default as we discover, pick and enable the persistence layer.\n * @internal\n */\nexport const defaultMsalValues = {\n tokenCache: {\n name: \"msal.cache\",\n // Expected values:\n // - Darwin: '/Users/user/.IdentityService'\n // - Windows 8+: 'C:\\Users\\user\\AppData\\Local\\.IdentityService'\n // - Linux: '/home/user/.IdentityService'\n directory: path.join(localApplicationDataFolder, \".IdentityService\"),\n },\n keyRing: {\n label: \"MSALCache\",\n schema: \"msal.cache\",\n collection: \"default\",\n attributes: {\n MsalClientID: \"Microsoft.Developer.IdentityService\",\n \"Microsoft.Developer.IdentityService\": \"1.0.0.0\",\n },\n service: \"Microsoft.Developer.IdentityService\",\n account: \"MSALCache\",\n },\n keyChain: {\n service: \"Microsoft.Developer.IdentityService\",\n account: \"MSALCache\",\n },\n};\n\n/**\n * Options that are used by the underlying MSAL cache provider.\n * @internal\n */\nexport type MsalPersistenceOptions = Omit<TokenCachePersistenceOptions, \"enabled\">;\n\n/**\n * A function that returns a persistent token cache instance.\n * @internal\n */\ntype MsalPersistenceFactory = (options?: MsalPersistenceOptions) => Promise<Persistence>;\n\n/**\n * Expected responses:\n * - Darwin: '/Users/user/.IdentityService/<name>'\n * - Windows 8+: 'C:\\Users\\user\\AppData\\Local\\.IdentityService\\<name>'\n * - Linux: '/home/user/.IdentityService/<name>'\n * @internal\n */\nfunction getPersistencePath(name: string): string {\n return path.join(defaultMsalValues.tokenCache.directory, name);\n}\n\n/**\n * Set of the platforms we attempt to deliver persistence on.\n *\n * - On Windows we use DPAPI.\n * - On OSX (Darwin), we try to use the system's Keychain, otherwise if the property `unsafeAllowUnencryptedStorage` is set to true, we use an unencrypted file.\n * - On Linux, we try to use the system's Keyring, otherwise if the property `unsafeAllowUnencryptedStorage` is set to true, we use an unencrypted file.\n *\n * Other platforms _are not supported_ at this time.\n *\n * @internal\n */\nexport const msalPersistencePlatforms: Partial<Record<NodeJS.Platform, MsalPersistenceFactory>> = {\n win32: ({ name = defaultMsalValues.tokenCache.name } = {}): Promise<Persistence> =>\n FilePersistenceWithDataProtection.create(\n getPersistencePath(name),\n DataProtectionScope.CurrentUser,\n ),\n\n darwin: async (options: MsalPersistenceOptions = {}): Promise<Persistence> => {\n const { name, unsafeAllowUnencryptedStorage } = options;\n const { service, account } = defaultMsalValues.keyChain;\n const persistencePath = getPersistencePath(name || defaultMsalValues.tokenCache.name);\n\n try {\n const persistence = await KeychainPersistence.create(persistencePath, service, account);\n // If we don't encounter an error when trying to read from the keychain, then we should be good to go.\n await persistence.load();\n return persistence;\n } catch (e: any) {\n // If we got an error while trying to read from the keyring,\n // we will proceed only if the user has specified that unencrypted storage is allowed.\n if (!unsafeAllowUnencryptedStorage) {\n throw new Error(\"Unable to read from the macOS Keychain.\");\n }\n return FilePersistence.create(persistencePath);\n }\n },\n\n linux: async (options: MsalPersistenceOptions = {}): Promise<Persistence> => {\n const { name, unsafeAllowUnencryptedStorage } = options;\n const { service, account } = defaultMsalValues.keyRing;\n const persistencePath = getPersistencePath(name || defaultMsalValues.tokenCache.name);\n\n try {\n const persistence = await LibSecretPersistence.create(persistencePath, service, account);\n // If we don't encounter an error when trying to read from the keyring, then we should be good to go.\n await persistence.load();\n return persistence;\n } catch (e: any) {\n // If we got an error while trying to read from the keyring,\n // we will proceed only if the user has specified that unencrypted storage is allowed.\n if (!unsafeAllowUnencryptedStorage) {\n throw new Error(\"Unable to read from the system keyring (libsecret).\");\n }\n return FilePersistence.create(persistencePath);\n }\n },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { MsalPersistenceOptions, msalPersistencePlatforms } from \"./platforms\";\nimport { IPersistence as Persistence, PersistenceCachePlugin } from \"@azure/msal-node-extensions\";\nimport { ICachePlugin as CachePlugin } from \"@azure/msal-node\";\n\n/**\n * This is used to gain access to the underlying Persistence instance, which we use for testing\n *\n * @returns a raw persistence instance\n * @internal\n */\nexport async function createPersistence(options: MsalPersistenceOptions): Promise<Persistence> {\n const persistence = await msalPersistencePlatforms[process.platform]?.(options);\n\n if (persistence === undefined) {\n throw new Error(\"no persistence providers are available on this platform\");\n }\n\n return persistence;\n}\n\nexport async function createPersistenceCachePlugin(\n options?: MsalPersistenceOptions,\n): Promise<CachePlugin> {\n const persistence = await createPersistence(options ?? {});\n\n return new PersistenceCachePlugin(persistence, {\n retryNumber: 100,\n retryDelay: 50,\n });\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzurePluginContext } from \"../../identity/src/plugins/provider\";\nimport { IdentityPlugin } from \"@azure/identity\";\nimport { createPersistenceCachePlugin } from \"./provider\";\n\n/**\n * A plugin that provides persistent token caching for `@azure/identity`\n * credentials. The plugin API is compatible with `@azure/identity` versions\n * 2.0.0 and later. Load this plugin using the `useIdentityPlugin`\n * function, imported from `@azure/identity`.\n *\n * In order to enable this functionality, you must also pass\n * `tokenCachePersistenceOptions` to your credential constructors with an\n * `enabled` property set to true.\n *\n * Example:\n *\n * ```ts snippet:device_code_credential_example\n * import { DeviceCodeCredential } from \"@azure/identity\";\n *\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true,\n * },\n * });\n * // We'll use the Microsoft Graph scope as an example\n * const scope = \"https://graph.microsoft.com/.default\";\n * // Print out part of the access token\n * console.log((await credential.getToken(scope)).token.substring(0, 10), \"...\");\n * ```\n */\n\nexport const cachePersistencePlugin: IdentityPlugin = (context) => {\n const { cachePluginControl } = context as AzurePluginContext;\n\n cachePluginControl.setPersistence(createPersistenceCachePlugin);\n};\n"],"names":["path","FilePersistenceWithDataProtection","DataProtectionScope","__awaiter","KeychainPersistence","FilePersistence","LibSecretPersistence","PersistenceCachePlugin"],"mappings":"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"}
|
|
@@ -19,7 +19,14 @@ export class ChainedTokenCredential {
|
|
|
19
19
|
* @param sources - `TokenCredential` implementations to be tried in order.
|
|
20
20
|
*
|
|
21
21
|
* Example usage:
|
|
22
|
-
* ```
|
|
22
|
+
* ```ts snippet:chained_token_credential_example
|
|
23
|
+
* import { ClientSecretCredential, ChainedTokenCredential } from "@azure/identity";
|
|
24
|
+
*
|
|
25
|
+
* const tenantId = "<tenant-id>";
|
|
26
|
+
* const clientId = "<client-id>";
|
|
27
|
+
* const clientSecret = "<client-secret>";
|
|
28
|
+
* const anotherClientId = "<another-client-id>";
|
|
29
|
+
* const anotherSecret = "<another-client-secret>";
|
|
23
30
|
* const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
|
|
24
31
|
* const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
|
|
25
32
|
* const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chainedTokenCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/chainedTokenCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAEjE;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAGjC
|
|
1
|
+
{"version":3,"file":"chainedTokenCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/chainedTokenCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAEjE;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAGjC;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,GAAG,OAA0B;QArBjC,aAAQ,GAAsB,EAAE,CAAC;QAsBvC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;;;OAYG;IACG,QAAQ;6DAAC,MAAyB,EAAE,UAA2B,EAAE;YACrE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/D,OAAO,KAAK,CAAC;QACf,CAAC;KAAA;IAEa,gBAAgB;6DAC5B,MAAyB,EACzB,UAA2B,EAAE;YAE7B,IAAI,KAAK,GAAuB,IAAI,CAAC;YACrC,IAAI,oBAAqC,CAAC;YAC1C,MAAM,MAAM,GAAY,EAAE,CAAC;YAE3B,OAAO,aAAa,CAAC,QAAQ,CAC3B,iCAAiC,EACjC,OAAO,EACP,CAAO,cAAc,EAAE,EAAE;gBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBAChE,IAAI,CAAC;wBACH,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;wBAChE,oBAAoB,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC1C,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBAClB,IACE,GAAG,CAAC,IAAI,KAAK,4BAA4B;4BACzC,GAAG,CAAC,IAAI,KAAK,6BAA6B,EAC1C,CAAC;4BACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBACnB,CAAC;6BAAM,CAAC;4BACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;4BAC/C,MAAM,GAAG,CAAC;wBACZ,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAChC,MAAM,GAAG,GAAG,IAAI,4BAA4B,CAC1C,MAAM,EACN,+CAA+C,CAChD,CAAC;oBACF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC/C,MAAM,GAAG,CAAC;gBACZ,CAAC;gBAED,MAAM,CAAC,QAAQ,CAAC,IAAI,CAClB,cAAc,oBAAoB,CAAC,WAAW,CAAC,IAAI,KAAK,aAAa,CAAC,MAAM,CAAC,EAAE,CAChF,CAAC;gBAEF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACnB,MAAM,IAAI,0BAA0B,CAAC,kCAAkC,CAAC,CAAC;gBAC3E,CAAC;gBACD,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;YACzC,CAAC,CAAA,CACF,CAAC;QACJ,CAAC;KAAA;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport { AggregateAuthenticationError, CredentialUnavailableError } from \"../errors\";\nimport { credentialLogger, formatError, formatSuccess } from \"../util/logging\";\nimport { tracingClient } from \"../util/tracing\";\n\n/**\n * @internal\n */\nexport const logger = credentialLogger(\"ChainedTokenCredential\");\n\n/**\n * Enables multiple `TokenCredential` implementations to be tried in order\n * until one of the getToken methods returns an access token.\n */\nexport class ChainedTokenCredential implements TokenCredential {\n private _sources: TokenCredential[] = [];\n\n /**\n * Creates an instance of ChainedTokenCredential using the given credentials.\n *\n * @param sources - `TokenCredential` implementations to be tried in order.\n *\n * Example usage:\n * ```ts snippet:chained_token_credential_example\n * import { ClientSecretCredential, ChainedTokenCredential } from \"@azure/identity\";\n *\n * const tenantId = \"<tenant-id>\";\n * const clientId = \"<client-id>\";\n * const clientSecret = \"<client-secret>\";\n * const anotherClientId = \"<another-client-id>\";\n * const anotherSecret = \"<another-client-secret>\";\n * const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);\n * const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);\n * const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);\n * ```\n */\n constructor(...sources: TokenCredential[]) {\n this._sources = sources;\n }\n\n /**\n * Returns the first access token returned by one of the chained\n * `TokenCredential` implementations. Throws an {@link AggregateAuthenticationError}\n * when one or more credentials throws an {@link AuthenticationError} and\n * no credentials have returned an access token.\n *\n * This method is called automatically by Azure SDK client libraries. You may call this method\n * directly, but you must also handle token caching and token refreshing.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * `TokenCredential` implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n const { token } = await this.getTokenInternal(scopes, options);\n return token;\n }\n\n private async getTokenInternal(\n scopes: string | string[],\n options: GetTokenOptions = {},\n ): Promise<{ token: AccessToken; successfulCredential: TokenCredential }> {\n let token: AccessToken | null = null;\n let successfulCredential: TokenCredential;\n const errors: Error[] = [];\n\n return tracingClient.withSpan(\n \"ChainedTokenCredential.getToken\",\n options,\n async (updatedOptions) => {\n for (let i = 0; i < this._sources.length && token === null; i++) {\n try {\n token = await this._sources[i].getToken(scopes, updatedOptions);\n successfulCredential = this._sources[i];\n } catch (err: any) {\n if (\n err.name === \"CredentialUnavailableError\" ||\n err.name === \"AuthenticationRequiredError\"\n ) {\n errors.push(err);\n } else {\n logger.getToken.info(formatError(scopes, err));\n throw err;\n }\n }\n }\n\n if (!token && errors.length > 0) {\n const err = new AggregateAuthenticationError(\n errors,\n \"ChainedTokenCredential authentication failed.\",\n );\n logger.getToken.info(formatError(scopes, err));\n throw err;\n }\n\n logger.getToken.info(\n `Result for ${successfulCredential.constructor.name}: ${formatSuccess(scopes)}`,\n );\n\n if (token === null) {\n throw new CredentialUnavailableError(\"Failed to retrieve a valid token\");\n }\n return { token, successfulCredential };\n },\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentialPersistenceOptions.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/credentialPersistenceOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { TokenCachePersistenceOptions } from \"../msal/nodeFlows/tokenCachePersistenceOptions\";\n\n/**\n * Shared configuration options for credentials that support persistent token\n * caching.\n */\nexport interface CredentialPersistenceOptions {\n /**\n * Options to provide to the persistence layer (if one is available) when\n * storing credentials.\n *\n * You must first register a persistence provider plugin. See the\n * `@azure/identity-cache-persistence` package on NPM.\n *\n * Example:\n *\n * ```
|
|
1
|
+
{"version":3,"file":"credentialPersistenceOptions.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/credentialPersistenceOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { TokenCachePersistenceOptions } from \"../msal/nodeFlows/tokenCachePersistenceOptions\";\n\n/**\n * Shared configuration options for credentials that support persistent token\n * caching.\n */\nexport interface CredentialPersistenceOptions {\n /**\n * Options to provide to the persistence layer (if one is available) when\n * storing credentials.\n *\n * You must first register a persistence provider plugin. See the\n * `@azure/identity-cache-persistence` package on NPM.\n *\n * Example:\n *\n * ```ts snippet:credential_persistence_options_example\n * import { useIdentityPlugin, DeviceCodeCredential } from \"@azure/identity\";\n *\n * useIdentityPlugin(cachePersistencePlugin);\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true,\n * },\n * });\n * ```\n */\n\n tokenCachePersistenceOptions?: TokenCachePersistenceOptions;\n}\n"]}
|
|
@@ -28,13 +28,15 @@ export class DeviceCodeCredential {
|
|
|
28
28
|
*
|
|
29
29
|
* Developers can configure how this message is shown by passing a custom `userPromptCallback`:
|
|
30
30
|
*
|
|
31
|
-
* ```
|
|
31
|
+
* ```ts snippet:device_code_credential_example
|
|
32
|
+
* import { DeviceCodeCredential } from "@azure/identity";
|
|
33
|
+
*
|
|
32
34
|
* const credential = new DeviceCodeCredential({
|
|
33
|
-
* tenantId: env.AZURE_TENANT_ID,
|
|
34
|
-
* clientId: env.AZURE_CLIENT_ID,
|
|
35
|
+
* tenantId: process.env.AZURE_TENANT_ID,
|
|
36
|
+
* clientId: process.env.AZURE_CLIENT_ID,
|
|
35
37
|
* userPromptCallback: (info) => {
|
|
36
38
|
* console.log("CUSTOMIZED PROMPT CALLBACK", info.message);
|
|
37
|
-
* }
|
|
39
|
+
* },
|
|
38
40
|
* });
|
|
39
41
|
* ```
|
|
40
42
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceCodeCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/deviceCodeCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EACL,yBAAyB,EACzB,mCAAmC,EACnC,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAc,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,MAAM,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,UAAU,+BAA+B,CAAC,cAA8B;IAC5E,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAO/B
|
|
1
|
+
{"version":3,"file":"deviceCodeCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/deviceCodeCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport {\n processMultiTenantRequest,\n resolveAdditionallyAllowedTenantIds,\n resolveTenantId,\n} from \"../util/tenantIdUtils\";\nimport {\n DeviceCodeCredentialOptions,\n DeviceCodeInfo,\n DeviceCodePromptCallback,\n} from \"./deviceCodeCredentialOptions\";\nimport { AuthenticationRecord } from \"../msal/types\";\nimport { credentialLogger } from \"../util/logging\";\nimport { ensureScopes } from \"../util/scopeUtils\";\nimport { tracingClient } from \"../util/tracing\";\nimport { MsalClient, createMsalClient } from \"../msal/nodeFlows/msalClient\";\nimport { DeveloperSignOnClientId } from \"../constants\";\n\nconst logger = credentialLogger(\"DeviceCodeCredential\");\n\n/**\n * Method that logs the user code from the DeviceCodeCredential.\n * @param deviceCodeInfo - The device code.\n */\nexport function defaultDeviceCodePromptCallback(deviceCodeInfo: DeviceCodeInfo): void {\n console.log(deviceCodeInfo.message);\n}\n\n/**\n * Enables authentication to Microsoft Entra ID using a device code\n * that the user can enter into https://microsoft.com/devicelogin.\n */\nexport class DeviceCodeCredential implements TokenCredential {\n private tenantId?: string;\n private additionallyAllowedTenantIds: string[];\n private disableAutomaticAuthentication?: boolean;\n private msalClient: MsalClient;\n private userPromptCallback: DeviceCodePromptCallback;\n\n /**\n * Creates an instance of DeviceCodeCredential with the details needed\n * to initiate the device code authorization flow with Microsoft Entra ID.\n *\n * A message will be logged, giving users a code that they can use to authenticate once they go to https://microsoft.com/devicelogin\n *\n * Developers can configure how this message is shown by passing a custom `userPromptCallback`:\n *\n * ```ts snippet:device_code_credential_example\n * import { DeviceCodeCredential } from \"@azure/identity\";\n *\n * const credential = new DeviceCodeCredential({\n * tenantId: process.env.AZURE_TENANT_ID,\n * clientId: process.env.AZURE_CLIENT_ID,\n * userPromptCallback: (info) => {\n * console.log(\"CUSTOMIZED PROMPT CALLBACK\", info.message);\n * },\n * });\n * ```\n *\n * @param options - Options for configuring the client which makes the authentication requests.\n */\n constructor(options?: DeviceCodeCredentialOptions) {\n this.tenantId = options?.tenantId;\n this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n options?.additionallyAllowedTenants,\n );\n const clientId = options?.clientId ?? DeveloperSignOnClientId;\n const tenantId = resolveTenantId(logger, options?.tenantId, clientId);\n this.userPromptCallback = options?.userPromptCallback ?? defaultDeviceCodePromptCallback;\n this.msalClient = createMsalClient(clientId, tenantId, {\n ...options,\n logger,\n tokenCredentialOptions: options || {},\n });\n this.disableAutomaticAuthentication = options?.disableAutomaticAuthentication;\n }\n\n /**\n * Authenticates with Microsoft Entra ID and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * If the user provided the option `disableAutomaticAuthentication`,\n * once the token can't be retrieved silently,\n * this method won't attempt to request user interaction to retrieve the token.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(\n `${this.constructor.name}.getToken`,\n options,\n async (newOptions) => {\n newOptions.tenantId = processMultiTenantRequest(\n this.tenantId,\n newOptions,\n this.additionallyAllowedTenantIds,\n logger,\n );\n\n const arrayScopes = ensureScopes(scopes);\n return this.msalClient.getTokenByDeviceCode(arrayScopes, this.userPromptCallback, {\n ...newOptions,\n disableAutomaticAuthentication: this.disableAutomaticAuthentication,\n });\n },\n );\n }\n\n /**\n * Authenticates with Microsoft Entra ID and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * If the token can't be retrieved silently, this method will always generate a challenge for the user.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async authenticate(\n scopes: string | string[],\n options: GetTokenOptions = {},\n ): Promise<AuthenticationRecord | undefined> {\n return tracingClient.withSpan(\n `${this.constructor.name}.authenticate`,\n options,\n async (newOptions) => {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n await this.msalClient.getTokenByDeviceCode(arrayScopes, this.userPromptCallback, {\n ...newOptions,\n disableAutomaticAuthentication: false, // this method should always allow user interaction\n });\n return this.msalClient.getActiveAccount();\n },\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onBehalfOfCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/onBehalfOfCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport { MsalClient, createMsalClient } from \"../msal/nodeFlows/msalClient\";\nimport {\n OnBehalfOfCredentialAssertionOptions,\n OnBehalfOfCredentialCertificateOptions,\n OnBehalfOfCredentialOptions,\n OnBehalfOfCredentialSecretOptions,\n} from \"./onBehalfOfCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport {\n processMultiTenantRequest,\n resolveAdditionallyAllowedTenantIds,\n} from \"../util/tenantIdUtils\";\n\nimport { CertificateParts } from \"../msal/types\";\nimport { ClientCertificatePEMCertificatePath } from \"./clientCertificateCredential\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\nimport { CredentialUnavailableError } from \"../errors\";\nimport { MultiTenantTokenCredentialOptions } from \"./multiTenantTokenCredentialOptions\";\nimport { createHash } from \"node:crypto\";\nimport { ensureScopes } from \"../util/scopeUtils\";\nimport { readFile } from \"node:fs/promises\";\nimport { tracingClient } from \"../util/tracing\";\n\nconst credentialName = \"OnBehalfOfCredential\";\nconst logger = credentialLogger(credentialName);\n\n/**\n * Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow).\n */\nexport class OnBehalfOfCredential implements TokenCredential {\n private tenantId: string;\n private additionallyAllowedTenantIds: string[];\n private msalClient: MsalClient;\n private sendCertificateChain?: boolean;\n private certificatePath?: string;\n private clientSecret?: string;\n private userAssertionToken: string;\n private clientAssertion?: () => Promise<string>;\n\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with path to a PEM certificate,\n * and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId,\n * clientId,\n * certificatePath: \"/path/to/certificate.pem\",\n * userAssertionToken: \"access-token\"\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n *\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialCertificateOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with a client\n * secret and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId,\n * clientId,\n * clientSecret,\n * userAssertionToken: \"access-token\"\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n *\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialSecretOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with a client `getAssertion`\n * and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId,\n * clientId,\n * getAssertion: () => { return Promise.resolve(\"my-jwt\")},\n * userAssertionToken: \"access-token\"\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n *\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialAssertionOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n\n constructor(options: OnBehalfOfCredentialOptions) {\n const { clientSecret } = options as OnBehalfOfCredentialSecretOptions;\n const { certificatePath, sendCertificateChain } =\n options as OnBehalfOfCredentialCertificateOptions;\n const { getAssertion } = options as OnBehalfOfCredentialAssertionOptions;\n const {\n tenantId,\n clientId,\n userAssertionToken,\n additionallyAllowedTenants: additionallyAllowedTenantIds,\n } = options;\n if (!tenantId) {\n throw new CredentialUnavailableError(\n `${credentialName}: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!clientId) {\n throw new CredentialUnavailableError(\n `${credentialName}: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!clientSecret && !certificatePath && !getAssertion) {\n throw new CredentialUnavailableError(\n `${credentialName}: You must provide one of clientSecret, certificatePath, or a getAssertion callback but none were provided. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!userAssertionToken) {\n throw new CredentialUnavailableError(\n `${credentialName}: userAssertionToken is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n this.certificatePath = certificatePath;\n this.clientSecret = clientSecret;\n this.userAssertionToken = userAssertionToken;\n this.sendCertificateChain = sendCertificateChain;\n this.clientAssertion = getAssertion;\n\n this.tenantId = tenantId;\n this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n additionallyAllowedTenantIds,\n );\n\n this.msalClient = createMsalClient(clientId, this.tenantId, {\n ...options,\n logger,\n tokenCredentialOptions: options,\n });\n }\n\n /**\n * Authenticates with Microsoft Entra ID and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure the underlying network requests.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {\n newOptions.tenantId = processMultiTenantRequest(\n this.tenantId,\n newOptions,\n this.additionallyAllowedTenantIds,\n logger,\n );\n\n const arrayScopes = ensureScopes(scopes);\n if (this.certificatePath) {\n const clientCertificate = await this.buildClientCertificate(this.certificatePath);\n\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n clientCertificate,\n newOptions,\n );\n } else if (this.clientSecret) {\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n this.clientSecret,\n options,\n );\n } else if (this.clientAssertion) {\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n this.clientAssertion,\n options,\n );\n } else {\n // this is an invalid scenario and is a bug, as the constructor should have thrown an error if neither clientSecret nor certificatePath nor clientAssertion were provided\n throw new Error(\n \"Expected either clientSecret or certificatePath or clientAssertion to be defined.\",\n );\n }\n });\n }\n\n private async buildClientCertificate(certificatePath: string): Promise<CertificateParts> {\n try {\n const parts = await this.parseCertificate({ certificatePath }, this.sendCertificateChain);\n return {\n thumbprint: parts.thumbprint,\n privateKey: parts.certificateContents,\n x5c: parts.x5c,\n };\n } catch (error: any) {\n logger.info(formatError(\"\", error));\n throw error;\n }\n }\n\n private async parseCertificate(\n configuration: ClientCertificatePEMCertificatePath,\n sendCertificateChain?: boolean,\n ): Promise<Omit<CertificateParts, \"privateKey\"> & { certificateContents: string }> {\n const certificatePath = configuration.certificatePath;\n const certificateContents = await readFile(certificatePath, \"utf8\");\n const x5c = sendCertificateChain ? certificateContents : undefined;\n\n const certificatePattern =\n /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\n const publicKeys: string[] = [];\n\n // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c\n let match;\n do {\n match = certificatePattern.exec(certificateContents);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n throw new Error(\"The file at the specified path does not contain a PEM-encoded certificate.\");\n }\n\n const thumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n return {\n certificateContents,\n thumbprint,\n x5c,\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"onBehalfOfCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/onBehalfOfCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport { MsalClient, createMsalClient } from \"../msal/nodeFlows/msalClient\";\nimport {\n OnBehalfOfCredentialAssertionOptions,\n OnBehalfOfCredentialCertificateOptions,\n OnBehalfOfCredentialOptions,\n OnBehalfOfCredentialSecretOptions,\n} from \"./onBehalfOfCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport {\n processMultiTenantRequest,\n resolveAdditionallyAllowedTenantIds,\n} from \"../util/tenantIdUtils\";\n\nimport { CertificateParts } from \"../msal/types\";\nimport { ClientCertificatePEMCertificatePath } from \"./clientCertificateCredential\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\nimport { CredentialUnavailableError } from \"../errors\";\nimport { MultiTenantTokenCredentialOptions } from \"./multiTenantTokenCredentialOptions\";\nimport { createHash } from \"node:crypto\";\nimport { ensureScopes } from \"../util/scopeUtils\";\nimport { readFile } from \"node:fs/promises\";\nimport { tracingClient } from \"../util/tracing\";\n\nconst credentialName = \"OnBehalfOfCredential\";\nconst logger = credentialLogger(credentialName);\n\n/**\n * Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow).\n */\nexport class OnBehalfOfCredential implements TokenCredential {\n private tenantId: string;\n private additionallyAllowedTenantIds: string[];\n private msalClient: MsalClient;\n private sendCertificateChain?: boolean;\n private certificatePath?: string;\n private clientSecret?: string;\n private userAssertionToken: string;\n private clientAssertion?: () => Promise<string>;\n\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with path to a PEM certificate,\n * and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts snippet:on_behalf_of_credential_pem_example\n * import { OnBehalfOfCredential } from \"@azure/identity\";\n * import { KeyClient } from \"@azure/keyvault-keys\";\n *\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId: \"tenant-id\",\n * clientId: \"client-id\",\n * certificatePath: \"/path/to/certificate.pem\",\n * userAssertionToken: \"access-token\",\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialCertificateOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with a client\n * secret and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts snippet:on_behalf_of_credential_secret_example\n * import { OnBehalfOfCredential } from \"@azure/identity\";\n * import { KeyClient } from \"@azure/keyvault-keys\";\n *\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId: \"tenant-id\",\n * clientId: \"client-id\",\n * clientSecret: \"client-secret\",\n * userAssertionToken: \"access-token\",\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialSecretOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with a client `getAssertion`\n * and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts snippet:on_behalf_of_credential_assertion_example\n * import { OnBehalfOfCredential } from \"@azure/identity\";\n * import { KeyClient } from \"@azure/keyvault-keys\";\n *\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId: \"tenant-id\",\n * clientId: \"client-id\",\n * getAssertion: () => {\n * return Promise.resolve(\"my-jwt\");\n * },\n * userAssertionToken: \"access-token\",\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialAssertionOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n\n constructor(options: OnBehalfOfCredentialOptions) {\n const { clientSecret } = options as OnBehalfOfCredentialSecretOptions;\n const { certificatePath, sendCertificateChain } =\n options as OnBehalfOfCredentialCertificateOptions;\n const { getAssertion } = options as OnBehalfOfCredentialAssertionOptions;\n const {\n tenantId,\n clientId,\n userAssertionToken,\n additionallyAllowedTenants: additionallyAllowedTenantIds,\n } = options;\n if (!tenantId) {\n throw new CredentialUnavailableError(\n `${credentialName}: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!clientId) {\n throw new CredentialUnavailableError(\n `${credentialName}: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!clientSecret && !certificatePath && !getAssertion) {\n throw new CredentialUnavailableError(\n `${credentialName}: You must provide one of clientSecret, certificatePath, or a getAssertion callback but none were provided. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!userAssertionToken) {\n throw new CredentialUnavailableError(\n `${credentialName}: userAssertionToken is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n this.certificatePath = certificatePath;\n this.clientSecret = clientSecret;\n this.userAssertionToken = userAssertionToken;\n this.sendCertificateChain = sendCertificateChain;\n this.clientAssertion = getAssertion;\n\n this.tenantId = tenantId;\n this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n additionallyAllowedTenantIds,\n );\n\n this.msalClient = createMsalClient(clientId, this.tenantId, {\n ...options,\n logger,\n tokenCredentialOptions: options,\n });\n }\n\n /**\n * Authenticates with Microsoft Entra ID and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure the underlying network requests.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {\n newOptions.tenantId = processMultiTenantRequest(\n this.tenantId,\n newOptions,\n this.additionallyAllowedTenantIds,\n logger,\n );\n\n const arrayScopes = ensureScopes(scopes);\n if (this.certificatePath) {\n const clientCertificate = await this.buildClientCertificate(this.certificatePath);\n\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n clientCertificate,\n newOptions,\n );\n } else if (this.clientSecret) {\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n this.clientSecret,\n options,\n );\n } else if (this.clientAssertion) {\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n this.clientAssertion,\n options,\n );\n } else {\n // this is an invalid scenario and is a bug, as the constructor should have thrown an error if neither clientSecret nor certificatePath nor clientAssertion were provided\n throw new Error(\n \"Expected either clientSecret or certificatePath or clientAssertion to be defined.\",\n );\n }\n });\n }\n\n private async buildClientCertificate(certificatePath: string): Promise<CertificateParts> {\n try {\n const parts = await this.parseCertificate({ certificatePath }, this.sendCertificateChain);\n return {\n thumbprint: parts.thumbprint,\n privateKey: parts.certificateContents,\n x5c: parts.x5c,\n };\n } catch (error: any) {\n logger.info(formatError(\"\", error));\n throw error;\n }\n }\n\n private async parseCertificate(\n configuration: ClientCertificatePEMCertificatePath,\n sendCertificateChain?: boolean,\n ): Promise<Omit<CertificateParts, \"privateKey\"> & { certificateContents: string }> {\n const certificatePath = configuration.certificatePath;\n const certificateContents = await readFile(certificatePath, \"utf8\");\n const x5c = sendCertificateChain ? certificateContents : undefined;\n\n const certificatePattern =\n /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\n const publicKeys: string[] = [];\n\n // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c\n let match;\n do {\n match = certificatePattern.exec(certificateContents);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n throw new Error(\"The file at the specified path does not contain a PEM-encoded certificate.\");\n }\n\n const thumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n return {\n certificateContents,\n thumbprint,\n x5c,\n };\n }\n}\n"]}
|
|
@@ -22,18 +22,16 @@ const pluginContext = {
|
|
|
22
22
|
*
|
|
23
23
|
* Example:
|
|
24
24
|
*
|
|
25
|
-
* ```
|
|
26
|
-
* import {
|
|
25
|
+
* ```ts snippet:consumer_example
|
|
26
|
+
* import { useIdentityPlugin, DeviceCodeCredential } from "@azure/identity";
|
|
27
27
|
*
|
|
28
|
-
* import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
|
|
29
28
|
* useIdentityPlugin(cachePersistencePlugin);
|
|
30
|
-
*
|
|
31
|
-
* // The plugin has the capability to extend `DefaultAzureCredential` and to
|
|
29
|
+
* // The plugin has the capability to extend `DeviceCodeCredential` and to
|
|
32
30
|
* // add middleware to the underlying credentials, such as persistence.
|
|
33
|
-
* const credential = new
|
|
31
|
+
* const credential = new DeviceCodeCredential({
|
|
34
32
|
* tokenCachePersistenceOptions: {
|
|
35
|
-
* enabled: true
|
|
36
|
-
* }
|
|
33
|
+
* enabled: true,
|
|
34
|
+
* },
|
|
37
35
|
* });
|
|
38
36
|
* ```
|
|
39
37
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumer.js","sourceRoot":"","sources":["../../../../../identity/src/plugins/consumer.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEpF;;;;GAIG;AACH,MAAM,aAAa,GAAuB;IACxC,kBAAkB,EAAE,wBAAwB;IAC5C,yBAAyB,EAAE,+BAA+B;IAC1D,uBAAuB,EAAE,uBAAuB;CACjD,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"consumer.js","sourceRoot":"","sources":["../../../../../identity/src/plugins/consumer.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEpF;;;;GAIG;AACH,MAAM,aAAa,GAAuB;IACxC,kBAAkB,EAAE,wBAAwB;IAC5C,yBAAyB,EAAE,+BAA+B;IAC1D,uBAAuB,EAAE,uBAAuB;CACjD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,MAAM,CAAC,aAAa,CAAC,CAAC;AACxB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzurePluginContext, IdentityPlugin } from \"./provider\";\nimport {\n msalNodeFlowCacheControl,\n msalNodeFlowNativeBrokerControl,\n} from \"../msal/nodeFlows/msalPlugins\";\n\nimport { vsCodeCredentialControl } from \"../credentials/visualStudioCodeCredential\";\n\n/**\n * The context passed to an Identity plugin. This contains objects that\n * plugins can use to set backend implementations.\n * @internal\n */\nconst pluginContext: AzurePluginContext = {\n cachePluginControl: msalNodeFlowCacheControl,\n nativeBrokerPluginControl: msalNodeFlowNativeBrokerControl,\n vsCodeCredentialControl: vsCodeCredentialControl,\n};\n\n/**\n * Extend Azure Identity with additional functionality. Pass a plugin from\n * a plugin package, such as:\n *\n * - `@azure/identity-cache-persistence`: provides persistent token caching\n * - `@azure/identity-vscode`: provides the dependencies of\n * `VisualStudioCodeCredential` and enables it\n *\n * Example:\n *\n * ```ts snippet:consumer_example\n * import { useIdentityPlugin, DeviceCodeCredential } from \"@azure/identity\";\n *\n * useIdentityPlugin(cachePersistencePlugin);\n * // The plugin has the capability to extend `DeviceCodeCredential` and to\n * // add middleware to the underlying credentials, such as persistence.\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true,\n * },\n * });\n * ```\n *\n * @param plugin - the plugin to register\n */\nexport function useIdentityPlugin(plugin: IdentityPlugin): void {\n plugin(pluginContext);\n}\n"]}
|
|
@@ -5,14 +5,14 @@ import { bearerTokenAuthenticationPolicy, createEmptyPipeline, createPipelineReq
|
|
|
5
5
|
/**
|
|
6
6
|
* Returns a callback that provides a bearer token.
|
|
7
7
|
* For example, the bearer token can be used to authenticate a request as follows:
|
|
8
|
-
* ```
|
|
9
|
-
* import { DefaultAzureCredential } from "@azure/identity";
|
|
8
|
+
* ```ts snippet:token_provider_example
|
|
9
|
+
* import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
|
|
10
|
+
* import { createPipelineRequest } from "@azure/core-rest-pipeline";
|
|
10
11
|
*
|
|
11
12
|
* const credential = new DefaultAzureCredential();
|
|
12
13
|
* const scope = "https://cognitiveservices.azure.com/.default";
|
|
13
14
|
* const getAccessToken = getBearerTokenProvider(credential, scope);
|
|
14
15
|
* const token = await getAccessToken();
|
|
15
|
-
*
|
|
16
16
|
* // usage
|
|
17
17
|
* const request = createPipelineRequest({ url: "https://example.com" });
|
|
18
18
|
* request.headers.set("Authorization", `Bearer ${token}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenProvider.js","sourceRoot":"","sources":["../../../../identity/src/tokenProvider.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAiBnC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAA2B,EAC3B,MAAyB,EACzB,OAAuC;IAEvC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IACtD,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,+BAA+B,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5E,SAAe,iBAAiB;;;YAC9B,sDAAsD;YACtD,sDAAsD;YACtD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,CACpC;gBACE,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CACvB,OAAO,CAAC,OAAO,CAAC;oBACd,OAAO;oBACP,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,OAAO,CAAC,OAAO;iBACzB,CAAC;aACL,EACD,qBAAqB,CAAC;gBACpB,GAAG,EAAE,qBAAqB;gBAC1B,WAAW;gBACX,cAAc;aACf,CAAC,CACH,CAAC;YACF,MAAM,WAAW,GAAG,MAAA,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,0CAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;KAAA;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { TokenCredential, TracingContext } from \"@azure/core-auth\";\nimport {\n bearerTokenAuthenticationPolicy,\n createEmptyPipeline,\n createPipelineRequest,\n} from \"@azure/core-rest-pipeline\";\n\n/**\n * The options to configure the token provider.\n */\nexport interface GetBearerTokenProviderOptions {\n /** The abort signal to abort requests to get tokens */\n abortSignal?: AbortSignal;\n /** The tracing options for the requests to get tokens */\n tracingOptions?: {\n /**\n * Tracing Context for the current request to get a token.\n */\n tracingContext?: TracingContext;\n };\n}\n\n/**\n * Returns a callback that provides a bearer token.\n * For example, the bearer token can be used to authenticate a request as follows:\n * ```
|
|
1
|
+
{"version":3,"file":"tokenProvider.js","sourceRoot":"","sources":["../../../../identity/src/tokenProvider.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAiBnC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAA2B,EAC3B,MAAyB,EACzB,OAAuC;IAEvC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IACtD,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,+BAA+B,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5E,SAAe,iBAAiB;;;YAC9B,sDAAsD;YACtD,sDAAsD;YACtD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,CACpC;gBACE,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CACvB,OAAO,CAAC,OAAO,CAAC;oBACd,OAAO;oBACP,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,OAAO,CAAC,OAAO;iBACzB,CAAC;aACL,EACD,qBAAqB,CAAC;gBACpB,GAAG,EAAE,qBAAqB;gBAC1B,WAAW;gBACX,cAAc;aACf,CAAC,CACH,CAAC;YACF,MAAM,WAAW,GAAG,MAAA,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,0CAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;KAAA;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { TokenCredential, TracingContext } from \"@azure/core-auth\";\nimport {\n bearerTokenAuthenticationPolicy,\n createEmptyPipeline,\n createPipelineRequest,\n} from \"@azure/core-rest-pipeline\";\n\n/**\n * The options to configure the token provider.\n */\nexport interface GetBearerTokenProviderOptions {\n /** The abort signal to abort requests to get tokens */\n abortSignal?: AbortSignal;\n /** The tracing options for the requests to get tokens */\n tracingOptions?: {\n /**\n * Tracing Context for the current request to get a token.\n */\n tracingContext?: TracingContext;\n };\n}\n\n/**\n * Returns a callback that provides a bearer token.\n * For example, the bearer token can be used to authenticate a request as follows:\n * ```ts snippet:token_provider_example\n * import { DefaultAzureCredential, getBearerTokenProvider } from \"@azure/identity\";\n * import { createPipelineRequest } from \"@azure/core-rest-pipeline\";\n *\n * const credential = new DefaultAzureCredential();\n * const scope = \"https://cognitiveservices.azure.com/.default\";\n * const getAccessToken = getBearerTokenProvider(credential, scope);\n * const token = await getAccessToken();\n * // usage\n * const request = createPipelineRequest({ url: \"https://example.com\" });\n * request.headers.set(\"Authorization\", `Bearer ${token}`);\n * ```\n *\n * @param credential - The credential used to authenticate the request.\n * @param scopes - The scopes required for the bearer token.\n * @param options - Options to configure the token provider.\n * @returns a callback that provides a bearer token.\n */\nexport function getBearerTokenProvider(\n credential: TokenCredential,\n scopes: string | string[],\n options?: GetBearerTokenProviderOptions,\n): () => Promise<string> {\n const { abortSignal, tracingOptions } = options || {};\n const pipeline = createEmptyPipeline();\n pipeline.addPolicy(bearerTokenAuthenticationPolicy({ credential, scopes }));\n async function getRefreshedToken(): Promise<string> {\n // Create a pipeline with just the bearer token policy\n // and run a dummy request through it to get the token\n const res = await pipeline.sendRequest(\n {\n sendRequest: (request) =>\n Promise.resolve({\n request,\n status: 200,\n headers: request.headers,\n }),\n },\n createPipelineRequest({\n url: \"https://example.com\",\n abortSignal,\n tracingOptions,\n }),\n );\n const accessToken = res.headers.get(\"authorization\")?.split(\" \")[1];\n if (!accessToken) {\n throw new Error(\"Failed to get access token\");\n }\n return accessToken;\n }\n return getRefreshedToken;\n}\n"]}
|
|
@@ -13,18 +13,18 @@ import { createPersistenceCachePlugin } from "./provider";
|
|
|
13
13
|
*
|
|
14
14
|
* Example:
|
|
15
15
|
*
|
|
16
|
-
* ```
|
|
17
|
-
* import {
|
|
18
|
-
* import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
|
|
19
|
-
*
|
|
20
|
-
* // Load the plugin
|
|
21
|
-
* useIdentityPlugin(cachePersistencePlugin);
|
|
16
|
+
* ```ts snippet:device_code_credential_example
|
|
17
|
+
* import { DeviceCodeCredential } from "@azure/identity";
|
|
22
18
|
*
|
|
23
19
|
* const credential = new DeviceCodeCredential({
|
|
24
20
|
* tokenCachePersistenceOptions: {
|
|
25
|
-
* enabled: true
|
|
26
|
-
* }
|
|
21
|
+
* enabled: true,
|
|
22
|
+
* },
|
|
27
23
|
* });
|
|
24
|
+
* // We'll use the Microsoft Graph scope as an example
|
|
25
|
+
* const scope = "https://graph.microsoft.com/.default";
|
|
26
|
+
* // Print out part of the access token
|
|
27
|
+
* console.log((await credential.getToken(scope)).token.substring(0, 10), "...");
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
export const cachePersistencePlugin = (context) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAmB,CAAC,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,kBAAkB,EAAE,GAAG,OAA6B,CAAC;IAE7D,kBAAkB,CAAC,cAAc,CAAC,4BAA4B,CAAC,CAAC;AAClE,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzurePluginContext } from \"../../identity/src/plugins/provider\";\nimport { IdentityPlugin } from \"@azure/identity\";\nimport { createPersistenceCachePlugin } from \"./provider\";\n\n/**\n * A plugin that provides persistent token caching for `@azure/identity`\n * credentials. The plugin API is compatible with `@azure/identity` versions\n * 2.0.0 and later. Load this plugin using the `useIdentityPlugin`\n * function, imported from `@azure/identity`.\n *\n * In order to enable this functionality, you must also pass\n * `tokenCachePersistenceOptions` to your credential constructors with an\n * `enabled` property set to true.\n *\n * Example:\n *\n * ```
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAmB,CAAC,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,kBAAkB,EAAE,GAAG,OAA6B,CAAC;IAE7D,kBAAkB,CAAC,cAAc,CAAC,4BAA4B,CAAC,CAAC;AAClE,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzurePluginContext } from \"../../identity/src/plugins/provider\";\nimport { IdentityPlugin } from \"@azure/identity\";\nimport { createPersistenceCachePlugin } from \"./provider\";\n\n/**\n * A plugin that provides persistent token caching for `@azure/identity`\n * credentials. The plugin API is compatible with `@azure/identity` versions\n * 2.0.0 and later. Load this plugin using the `useIdentityPlugin`\n * function, imported from `@azure/identity`.\n *\n * In order to enable this functionality, you must also pass\n * `tokenCachePersistenceOptions` to your credential constructors with an\n * `enabled` property set to true.\n *\n * Example:\n *\n * ```ts snippet:device_code_credential_example\n * import { DeviceCodeCredential } from \"@azure/identity\";\n *\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true,\n * },\n * });\n * // We'll use the Microsoft Graph scope as an example\n * const scope = \"https://graph.microsoft.com/.default\";\n * // Print out part of the access token\n * console.log((await credential.getToken(scope)).token.substring(0, 10), \"...\");\n * ```\n */\n\nexport const cachePersistencePlugin: IdentityPlugin = (context) => {\n const { cachePluginControl } = context as AzurePluginContext;\n\n cachePluginControl.setPersistence(createPersistenceCachePlugin);\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure/identity-cache-persistence",
|
|
3
|
-
"version": "1.1.2-alpha.
|
|
3
|
+
"version": "1.1.2-alpha.20240927.1",
|
|
4
4
|
"sdk-type": "client",
|
|
5
5
|
"description": "A secure, persistent token cache for Azure Identity credentials that uses the OS secret-management API",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,26 +8,27 @@
|
|
|
8
8
|
"types": "./types/identity-cache-persistence.d.ts",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit",
|
|
11
|
+
"build": "npm run clean && npm run extract-api && tsc -p . && dev-tool run bundle",
|
|
11
12
|
"build:samples": "echo skipped",
|
|
12
13
|
"build:test": "tsc -p . && dev-tool run bundle",
|
|
13
|
-
"build": "npm run clean && npm run extract-api && tsc -p . && dev-tool run bundle",
|
|
14
14
|
"check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"",
|
|
15
15
|
"clean": "rimraf --glob dist dist-* types *.tgz *.log",
|
|
16
16
|
"execute:samples": "echo skipped",
|
|
17
17
|
"extract-api": "tsc -p . && dev-tool run extract-api",
|
|
18
18
|
"format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\" \"samples-dev/**/*.ts\"",
|
|
19
|
+
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
|
|
19
20
|
"integration-test:browser": "echo skipped",
|
|
20
21
|
"integration-test:node": "echo skipped",
|
|
21
|
-
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
|
|
22
|
-
"lint:fix": "eslint package.json api-extractor.json README.md src test --fix --fix-type [problem,suggestion]",
|
|
23
22
|
"lint": "eslint package.json api-extractor.json README.md src test",
|
|
23
|
+
"lint:fix": "eslint package.json api-extractor.json README.md src test --fix --fix-type [problem,suggestion]",
|
|
24
24
|
"pack": "npm pack 2>&1",
|
|
25
|
+
"test": "npm run clean && npm run build:test && npm run unit-test && npm run integration-test",
|
|
25
26
|
"test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser",
|
|
26
27
|
"test:node": "npm run clean && npm run build:test && npm run unit-test:node && npm run integration-test:node",
|
|
27
|
-
"test": "npm run
|
|
28
|
+
"unit-test": "npm run unit-test:node && npm run unit-test:browser",
|
|
28
29
|
"unit-test:browser": "echo skipped",
|
|
29
|
-
"unit-test:node": "dev-tool run test:node-ts-input -- --timeout 300000 --exclude \"test/**/browser/**/*.spec.ts\" \"test/**/**/*.spec.ts\"",
|
|
30
|
-
"
|
|
30
|
+
"unit-test:node": "dev-tool run test:node-ts-input -- --timeout 300000 --exclude \"test/**/browser/**/*.spec.ts\" --exclude \"test/snippets.spec.ts\" \"test/**/**/*.spec.ts\"",
|
|
31
|
+
"update-snippets": "dev-tool run update-snippets"
|
|
31
32
|
},
|
|
32
33
|
"files": [
|
|
33
34
|
"dist/",
|
|
@@ -67,17 +68,18 @@
|
|
|
67
68
|
"tslib": "^2.2.0"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
71
|
+
"@azure-tools/test-recorder": "^3.0.0",
|
|
72
|
+
"@azure-tools/test-utils": "^1.0.1",
|
|
70
73
|
"@azure/core-client": "^1.7.0",
|
|
71
74
|
"@azure/dev-tool": ">=1.0.0-alpha <1.0.0-alphb",
|
|
72
75
|
"@azure/eslint-plugin-azure-sdk": ">=3.0.0-alpha <3.0.0-alphb",
|
|
73
76
|
"@azure/logger": "^1.0.4",
|
|
74
|
-
"@azure-tools/test-utils": "^1.0.1",
|
|
75
|
-
"@azure-tools/test-recorder": "^3.0.0",
|
|
76
77
|
"@microsoft/api-extractor": "^7.31.1",
|
|
77
78
|
"@types/jws": "^3.2.2",
|
|
78
79
|
"@types/mocha": "^10.0.0",
|
|
79
80
|
"@types/node": "^18.0.0",
|
|
80
81
|
"@types/qs": "^6.5.3",
|
|
82
|
+
"@types/sinon": "^17.0.0",
|
|
81
83
|
"cross-env": "^7.0.2",
|
|
82
84
|
"dotenv": "^16.0.0",
|
|
83
85
|
"eslint": "^9.9.0",
|
|
@@ -85,10 +87,9 @@
|
|
|
85
87
|
"mocha": "^10.0.0",
|
|
86
88
|
"puppeteer": "^23.0.2",
|
|
87
89
|
"rimraf": "^5.0.5",
|
|
88
|
-
"typescript": "~5.5.3",
|
|
89
|
-
"util": "^0.12.1",
|
|
90
90
|
"sinon": "^17.0.0",
|
|
91
|
-
"
|
|
92
|
-
"
|
|
91
|
+
"ts-node": "^10.0.0",
|
|
92
|
+
"typescript": "~5.6.2",
|
|
93
|
+
"util": "^0.12.1"
|
|
93
94
|
}
|
|
94
95
|
}
|
|
@@ -12,18 +12,18 @@ import { IdentityPlugin } from '@azure/identity';
|
|
|
12
12
|
*
|
|
13
13
|
* Example:
|
|
14
14
|
*
|
|
15
|
-
* ```
|
|
16
|
-
* import {
|
|
17
|
-
* import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
|
|
18
|
-
*
|
|
19
|
-
* // Load the plugin
|
|
20
|
-
* useIdentityPlugin(cachePersistencePlugin);
|
|
15
|
+
* ```ts snippet:device_code_credential_example
|
|
16
|
+
* import { DeviceCodeCredential } from "@azure/identity";
|
|
21
17
|
*
|
|
22
18
|
* const credential = new DeviceCodeCredential({
|
|
23
19
|
* tokenCachePersistenceOptions: {
|
|
24
|
-
* enabled: true
|
|
25
|
-
* }
|
|
20
|
+
* enabled: true,
|
|
21
|
+
* },
|
|
26
22
|
* });
|
|
23
|
+
* // We'll use the Microsoft Graph scope as an example
|
|
24
|
+
* const scope = "https://graph.microsoft.com/.default";
|
|
25
|
+
* // Print out part of the access token
|
|
26
|
+
* console.log((await credential.getToken(scope)).token.substring(0, 10), "...");
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export declare const cachePersistencePlugin: IdentityPlugin;
|