@azure/identity 2.0.4 → 2.1.0-alpha.20220307.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.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/CHANGELOG.md +13 -2
- package/dist/index.js +81 -41
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +1 -1
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js +7 -9
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +5 -2
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +16 -7
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +11 -5
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +10 -4
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +11 -5
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +20 -8
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
- package/dist-esm/src/index.js +1 -1
- package/dist-esm/src/index.js.map +1 -1
- package/package.json +4 -4
- package/types/identity.d.ts +60 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
## 2.1.0-beta.1 (2022-03-02)
|
|
4
|
+
|
|
5
|
+
### Features Added
|
|
6
|
+
|
|
7
|
+
- Added support for specifying a custom `resourceId` when creating a `ManagedIdentityCredential` or `DefaultAzureCredential`.
|
|
8
|
+
- In some scenarios where a user-assigned managed identity is required, the identity may be known by an ARM resource ID, but not a client ID (such as when user-assigned identities are created using an ARM template). The `resourceId` option allows an app to select its managed identity by its ARM resource ID to support such scenarios.
|
|
9
|
+
- If `resourceId` is provided, the managed identity providers for Azure App Service (2017), Azure Arc, Azure Cloud Shell, Azure Service Fabric and Token Exchange authentication will log a warning since this parameter is not supported by the identity endpoints in those services. The authentication attempts will be sent, but the parameter will be ignored by the service.
|
|
10
|
+
- Added `clientId` to the optional parameters of the `ManagedIdentityCredential`.
|
|
11
|
+
- Updated the Troubleshoot guide to have error codes and error messages for the Identity Customer Service Support.
|
|
12
|
+
|
|
3
13
|
## 2.0.4 (2022-02-18)
|
|
4
14
|
|
|
5
15
|
### Bugs Fixed
|
|
@@ -72,8 +82,8 @@ useIdentityPlugin(cachePersistencePlugin);
|
|
|
72
82
|
async function main() {
|
|
73
83
|
const credential = new DeviceCodeCredential({
|
|
74
84
|
tokenCachePersistenceOptions: {
|
|
75
|
-
enabled: true
|
|
76
|
-
}
|
|
85
|
+
enabled: true,
|
|
86
|
+
},
|
|
77
87
|
});
|
|
78
88
|
}
|
|
79
89
|
```
|
|
@@ -139,6 +149,7 @@ Azure Service Fabric support hasn't been added on the initial version 2 of Ident
|
|
|
139
149
|
- We have also renamed the error `CredentialUnavailable` to `CredentialUnavailableError`, to align with the naming convention used for error classes in the Azure SDKs in JavaScript.
|
|
140
150
|
- In v1 of Identity some `getToken` calls could resolve with `null` in the case the authentication request succeeded with a malformed output. In v2, issues with the `getToken` method will always throw errors.
|
|
141
151
|
- Breaking changes to InteractiveBrowserCredential
|
|
152
|
+
|
|
142
153
|
- The `InteractiveBrowserCredential` will use the [Auth Code Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) with [PKCE](https://tools.ietf.org/html/rfc7636) rather than [Implicit Grant Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-implicit-grant-flow) to better support browsers with enhanced security restrictions. Learn how to migrate in the [migration guide](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/migration-v1-v2.md). Read more about the latest `InteractiveBrowserCredential` [here](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/interactive-browser-credential.md).
|
|
143
154
|
- The default client ID used for `InteractiveBrowserCredential` was viable only in Node.js and not for the browser. Therefore, on v2 client ID is a required parameter when using this credential in browser apps.
|
|
144
155
|
- Identity v2 also removes the `postLogoutRedirectUri` from the options to the constructor for `InteractiveBrowserCredential`. This option wasn't being used. Instead of using this option, use MSAL directly. For more information, see [Authenticating with the @azure/msal-browser Public Client](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-the-azuremsal-browser-public-client).
|
package/dist/index.js
CHANGED
|
@@ -368,7 +368,7 @@ function getIdentityClientAuthorityHost(options) {
|
|
|
368
368
|
class IdentityClient extends coreClient.ServiceClient {
|
|
369
369
|
constructor(options) {
|
|
370
370
|
var _a;
|
|
371
|
-
const packageDetails = `azsdk-js-identity/2.0.
|
|
371
|
+
const packageDetails = `azsdk-js-identity/2.1.0-beta.1`;
|
|
372
372
|
const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
|
|
373
373
|
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
|
|
374
374
|
: `${packageDetails}`;
|
|
@@ -2242,7 +2242,7 @@ function prepareRequestOptions$5(scopes, clientId) {
|
|
|
2242
2242
|
* Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
|
|
2243
2243
|
*/
|
|
2244
2244
|
const appServiceMsi2017 = {
|
|
2245
|
-
async isAvailable(scopes) {
|
|
2245
|
+
async isAvailable({ scopes }) {
|
|
2246
2246
|
const resource = mapScopesToResource(scopes);
|
|
2247
2247
|
if (!resource) {
|
|
2248
2248
|
logger$a.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
|
|
@@ -2256,7 +2256,10 @@ const appServiceMsi2017 = {
|
|
|
2256
2256
|
return result;
|
|
2257
2257
|
},
|
|
2258
2258
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2259
|
-
const { identityClient, scopes, clientId } = configuration;
|
|
2259
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2260
|
+
if (resourceId) {
|
|
2261
|
+
logger$a.warning(`${msiName$5}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2262
|
+
}
|
|
2260
2263
|
logger$a.info(`${msiName$5}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
2261
2264
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
|
|
2262
2265
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
@@ -2272,7 +2275,7 @@ const logger$9 = credentialLogger(msiName$4);
|
|
|
2272
2275
|
/**
|
|
2273
2276
|
* Generates the options used on the request for an access token.
|
|
2274
2277
|
*/
|
|
2275
|
-
function prepareRequestOptions$4(scopes, clientId) {
|
|
2278
|
+
function prepareRequestOptions$4(scopes, clientId, resourceId) {
|
|
2276
2279
|
const resource = mapScopesToResource(scopes);
|
|
2277
2280
|
if (!resource) {
|
|
2278
2281
|
throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
|
|
@@ -2283,6 +2286,9 @@ function prepareRequestOptions$4(scopes, clientId) {
|
|
|
2283
2286
|
if (clientId) {
|
|
2284
2287
|
body.client_id = clientId;
|
|
2285
2288
|
}
|
|
2289
|
+
if (resourceId) {
|
|
2290
|
+
body.msi_res_id = resourceId;
|
|
2291
|
+
}
|
|
2286
2292
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2287
2293
|
if (!process.env.MSI_ENDPOINT) {
|
|
2288
2294
|
throw new Error(`${msiName$4}: Missing environment variable: MSI_ENDPOINT`);
|
|
@@ -2304,7 +2310,7 @@ function prepareRequestOptions$4(scopes, clientId) {
|
|
|
2304
2310
|
* Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
|
|
2305
2311
|
*/
|
|
2306
2312
|
const cloudShellMsi = {
|
|
2307
|
-
async isAvailable(scopes) {
|
|
2313
|
+
async isAvailable({ scopes }) {
|
|
2308
2314
|
const resource = mapScopesToResource(scopes);
|
|
2309
2315
|
if (!resource) {
|
|
2310
2316
|
logger$9.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
|
|
@@ -2317,12 +2323,15 @@ const cloudShellMsi = {
|
|
|
2317
2323
|
return result;
|
|
2318
2324
|
},
|
|
2319
2325
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2320
|
-
const { identityClient, scopes, clientId } = configuration;
|
|
2326
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2321
2327
|
if (clientId) {
|
|
2322
|
-
logger$9.warning(`${msiName$4}:
|
|
2328
|
+
logger$9.warning(`${msiName$4}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
2329
|
+
}
|
|
2330
|
+
if (resourceId) {
|
|
2331
|
+
logger$9.warning(`${msiName$4}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
|
2323
2332
|
}
|
|
2324
2333
|
logger$9.info(`${msiName$4}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
2325
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId)), {
|
|
2334
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
|
|
2326
2335
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2327
2336
|
allowInsecureConnection: true }));
|
|
2328
2337
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -2353,7 +2362,7 @@ function expiresOnParser$1(requestBody) {
|
|
|
2353
2362
|
/**
|
|
2354
2363
|
* Generates the options used on the request for an access token.
|
|
2355
2364
|
*/
|
|
2356
|
-
function prepareRequestOptions$3(scopes, clientId, options) {
|
|
2365
|
+
function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
|
|
2357
2366
|
var _a;
|
|
2358
2367
|
const resource = mapScopesToResource(scopes);
|
|
2359
2368
|
if (!resource) {
|
|
@@ -2371,6 +2380,9 @@ function prepareRequestOptions$3(scopes, clientId, options) {
|
|
|
2371
2380
|
if (clientId) {
|
|
2372
2381
|
queryParameters.client_id = clientId;
|
|
2373
2382
|
}
|
|
2383
|
+
if (resourceId) {
|
|
2384
|
+
queryParameters.msi_res_id = resourceId;
|
|
2385
|
+
}
|
|
2374
2386
|
const params = new URLSearchParams(queryParameters);
|
|
2375
2387
|
query = `?${params.toString()}`;
|
|
2376
2388
|
}
|
|
@@ -2400,7 +2412,7 @@ const imdsMsiRetryConfig = {
|
|
|
2400
2412
|
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
2401
2413
|
*/
|
|
2402
2414
|
const imdsMsi = {
|
|
2403
|
-
async isAvailable(scopes, identityClient, clientId, getTokenOptions) {
|
|
2415
|
+
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions, }) {
|
|
2404
2416
|
var _a, _b;
|
|
2405
2417
|
const resource = mapScopesToResource(scopes);
|
|
2406
2418
|
if (!resource) {
|
|
@@ -2412,7 +2424,10 @@ const imdsMsi = {
|
|
|
2412
2424
|
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
2413
2425
|
return true;
|
|
2414
2426
|
}
|
|
2415
|
-
|
|
2427
|
+
if (!identityClient) {
|
|
2428
|
+
throw new Error("Missing IdentityClient");
|
|
2429
|
+
}
|
|
2430
|
+
const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
|
|
2416
2431
|
skipMetadataHeader: true,
|
|
2417
2432
|
skipQuery: true,
|
|
2418
2433
|
});
|
|
@@ -2465,12 +2480,12 @@ const imdsMsi = {
|
|
|
2465
2480
|
}
|
|
2466
2481
|
},
|
|
2467
2482
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2468
|
-
const { identityClient, scopes, clientId } = configuration;
|
|
2483
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2469
2484
|
logger$8.info(`${msiName$3}: Using the Azure IMDS endpoint coming from the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
|
|
2470
2485
|
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
|
|
2471
2486
|
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
|
|
2472
2487
|
try {
|
|
2473
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId)), { allowInsecureConnection: true }));
|
|
2488
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
|
|
2474
2489
|
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$1);
|
|
2475
2490
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2476
2491
|
}
|
|
@@ -2493,7 +2508,7 @@ const logger$7 = credentialLogger(msiName$2);
|
|
|
2493
2508
|
/**
|
|
2494
2509
|
* Generates the options used on the request for an access token.
|
|
2495
2510
|
*/
|
|
2496
|
-
function prepareRequestOptions$2(scopes) {
|
|
2511
|
+
function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
2497
2512
|
const resource = mapScopesToResource(scopes);
|
|
2498
2513
|
if (!resource) {
|
|
2499
2514
|
throw new Error(`${msiName$2}: Multiple scopes are not supported.`);
|
|
@@ -2502,11 +2517,17 @@ function prepareRequestOptions$2(scopes) {
|
|
|
2502
2517
|
resource,
|
|
2503
2518
|
"api-version": azureArcAPIVersion,
|
|
2504
2519
|
};
|
|
2505
|
-
|
|
2520
|
+
if (clientId) {
|
|
2521
|
+
queryParameters.client_id = clientId;
|
|
2522
|
+
}
|
|
2523
|
+
if (resourceId) {
|
|
2524
|
+
queryParameters.msi_res_id = resourceId;
|
|
2525
|
+
}
|
|
2506
2526
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2507
2527
|
if (!process.env.IDENTITY_ENDPOINT) {
|
|
2508
2528
|
throw new Error(`${msiName$2}: Missing environment variable: IDENTITY_ENDPOINT`);
|
|
2509
2529
|
}
|
|
2530
|
+
const query = new URLSearchParams(queryParameters);
|
|
2510
2531
|
return coreRestPipeline.createPipelineRequest({
|
|
2511
2532
|
// Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
|
|
2512
2533
|
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
|
@@ -2553,7 +2574,7 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
2553
2574
|
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
|
|
2554
2575
|
*/
|
|
2555
2576
|
const arcMsi = {
|
|
2556
|
-
async isAvailable(scopes) {
|
|
2577
|
+
async isAvailable({ scopes }) {
|
|
2557
2578
|
const resource = mapScopesToResource(scopes);
|
|
2558
2579
|
if (!resource) {
|
|
2559
2580
|
logger$7.info(`${msiName$2}: Unavailable. Multiple scopes are not supported.`);
|
|
@@ -2567,12 +2588,15 @@ const arcMsi = {
|
|
|
2567
2588
|
},
|
|
2568
2589
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2569
2590
|
var _a;
|
|
2570
|
-
const { identityClient, scopes, clientId } = configuration;
|
|
2571
|
-
logger$7.info(`${msiName$2}: Authenticating.`);
|
|
2591
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2572
2592
|
if (clientId) {
|
|
2573
|
-
|
|
2593
|
+
logger$7.warning(`${msiName$2}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
2594
|
+
}
|
|
2595
|
+
if (resourceId) {
|
|
2596
|
+
logger$7.warning(`${msiName$2}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
|
|
2574
2597
|
}
|
|
2575
|
-
|
|
2598
|
+
logger$7.info(`${msiName$2}: Authenticating.`);
|
|
2599
|
+
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
|
2576
2600
|
const filePath = await filePathRequest(identityClient, requestOptions);
|
|
2577
2601
|
if (!filePath) {
|
|
2578
2602
|
throw new Error(`${msiName$2}: Failed to find the token file.`);
|
|
@@ -2641,7 +2665,7 @@ function tokenExchangeMsi() {
|
|
|
2641
2665
|
return azureFederatedTokenFileContent;
|
|
2642
2666
|
}
|
|
2643
2667
|
return {
|
|
2644
|
-
async isAvailable(
|
|
2668
|
+
async isAvailable({ clientId }) {
|
|
2645
2669
|
const env = process.env;
|
|
2646
2670
|
const result = Boolean((clientId || env.AZURE_CLIENT_ID) && env.AZURE_TENANT_ID && azureFederatedTokenFilePath);
|
|
2647
2671
|
if (!result) {
|
|
@@ -2691,7 +2715,7 @@ function expiresOnParser(requestBody) {
|
|
|
2691
2715
|
/**
|
|
2692
2716
|
* Generates the options used on the request for an access token.
|
|
2693
2717
|
*/
|
|
2694
|
-
function prepareRequestOptions(scopes, clientId) {
|
|
2718
|
+
function prepareRequestOptions(scopes, clientId, resourceId) {
|
|
2695
2719
|
const resource = mapScopesToResource(scopes);
|
|
2696
2720
|
if (!resource) {
|
|
2697
2721
|
throw new Error(`${msiName}: Multiple scopes are not supported.`);
|
|
@@ -2703,6 +2727,9 @@ function prepareRequestOptions(scopes, clientId) {
|
|
|
2703
2727
|
if (clientId) {
|
|
2704
2728
|
queryParameters.client_id = clientId;
|
|
2705
2729
|
}
|
|
2730
|
+
if (resourceId) {
|
|
2731
|
+
queryParameters.msi_res_id = resourceId;
|
|
2732
|
+
}
|
|
2706
2733
|
const query = new URLSearchParams(queryParameters);
|
|
2707
2734
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2708
2735
|
if (!process.env.IDENTITY_ENDPOINT) {
|
|
@@ -2724,7 +2751,7 @@ function prepareRequestOptions(scopes, clientId) {
|
|
|
2724
2751
|
* Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
|
|
2725
2752
|
*/
|
|
2726
2753
|
const fabricMsi = {
|
|
2727
|
-
async isAvailable(scopes) {
|
|
2754
|
+
async isAvailable({ scopes }) {
|
|
2728
2755
|
const resource = mapScopesToResource(scopes);
|
|
2729
2756
|
if (!resource) {
|
|
2730
2757
|
logger$5.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
|
|
@@ -2738,7 +2765,10 @@ const fabricMsi = {
|
|
|
2738
2765
|
return result;
|
|
2739
2766
|
},
|
|
2740
2767
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2741
|
-
const { scopes, identityClient, clientId } = configuration;
|
|
2768
|
+
const { scopes, identityClient, clientId, resourceId } = configuration;
|
|
2769
|
+
if (resourceId) {
|
|
2770
|
+
logger$5.warning(`${msiName}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2771
|
+
}
|
|
2742
2772
|
logger$5.info([
|
|
2743
2773
|
`${msiName}:`,
|
|
2744
2774
|
"Using the endpoint and the secret coming from the environment variables:",
|
|
@@ -2746,7 +2776,7 @@ const fabricMsi = {
|
|
|
2746
2776
|
"IDENTITY_HEADER=[REDACTED] and",
|
|
2747
2777
|
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
|
|
2748
2778
|
].join(" "));
|
|
2749
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId)));
|
|
2779
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)));
|
|
2750
2780
|
request.agent = new https__default["default"].Agent({
|
|
2751
2781
|
// This is necessary because Service Fabric provides a self-signed certificate.
|
|
2752
2782
|
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
|
@@ -2773,44 +2803,56 @@ class ManagedIdentityCredential {
|
|
|
2773
2803
|
* @hidden
|
|
2774
2804
|
*/
|
|
2775
2805
|
constructor(clientIdOrOptions, options) {
|
|
2806
|
+
var _a, _b;
|
|
2776
2807
|
this.isEndpointUnavailable = null;
|
|
2777
2808
|
let _options;
|
|
2778
2809
|
if (typeof clientIdOrOptions === "string") {
|
|
2779
|
-
// clientId, options constructor
|
|
2780
2810
|
this.clientId = clientIdOrOptions;
|
|
2781
2811
|
_options = options;
|
|
2782
2812
|
}
|
|
2783
2813
|
else {
|
|
2784
|
-
|
|
2814
|
+
this.clientId = (_a = clientIdOrOptions) === null || _a === void 0 ? void 0 : _a.clientId;
|
|
2785
2815
|
_options = clientIdOrOptions;
|
|
2786
2816
|
}
|
|
2817
|
+
this.resourceId = (_b = _options) === null || _b === void 0 ? void 0 : _b.resourceId;
|
|
2818
|
+
// For JavaScript users.
|
|
2819
|
+
if (this.clientId && this.resourceId) {
|
|
2820
|
+
throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
|
|
2821
|
+
}
|
|
2787
2822
|
this.identityClient = new IdentityClient(_options);
|
|
2788
2823
|
this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
|
|
2789
2824
|
maxRetries: 0,
|
|
2790
2825
|
} }));
|
|
2791
2826
|
}
|
|
2792
|
-
async cachedAvailableMSI(scopes,
|
|
2827
|
+
async cachedAvailableMSI(scopes, getTokenOptions) {
|
|
2793
2828
|
if (this.cachedMSI) {
|
|
2794
2829
|
return this.cachedMSI;
|
|
2795
2830
|
}
|
|
2796
2831
|
const MSIs = [fabricMsi, appServiceMsi2017, cloudShellMsi, arcMsi, tokenExchangeMsi(), imdsMsi];
|
|
2797
2832
|
for (const msi of MSIs) {
|
|
2798
|
-
if (await msi.isAvailable(
|
|
2833
|
+
if (await msi.isAvailable({
|
|
2834
|
+
scopes,
|
|
2835
|
+
identityClient: this.isAvailableIdentityClient,
|
|
2836
|
+
clientId: this.clientId,
|
|
2837
|
+
resourceId: this.resourceId,
|
|
2838
|
+
getTokenOptions,
|
|
2839
|
+
})) {
|
|
2799
2840
|
this.cachedMSI = msi;
|
|
2800
2841
|
return msi;
|
|
2801
2842
|
}
|
|
2802
2843
|
}
|
|
2803
2844
|
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
|
|
2804
2845
|
}
|
|
2805
|
-
async authenticateManagedIdentity(scopes,
|
|
2846
|
+
async authenticateManagedIdentity(scopes, getTokenOptions) {
|
|
2806
2847
|
const { span, updatedOptions } = createSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
|
|
2807
2848
|
try {
|
|
2808
2849
|
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
|
|
2809
|
-
const availableMSI = await this.cachedAvailableMSI(scopes,
|
|
2850
|
+
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
|
|
2810
2851
|
return availableMSI.getToken({
|
|
2811
2852
|
identityClient: this.identityClient,
|
|
2812
2853
|
scopes,
|
|
2813
|
-
clientId,
|
|
2854
|
+
clientId: this.clientId,
|
|
2855
|
+
resourceId: this.resourceId,
|
|
2814
2856
|
}, updatedOptions);
|
|
2815
2857
|
}
|
|
2816
2858
|
catch (err) {
|
|
@@ -2841,7 +2883,7 @@ class ManagedIdentityCredential {
|
|
|
2841
2883
|
// If it's null, it means we don't yet know whether
|
|
2842
2884
|
// the endpoint is available and need to check for it.
|
|
2843
2885
|
if (this.isEndpointUnavailable !== true) {
|
|
2844
|
-
result = await this.authenticateManagedIdentity(scopes,
|
|
2886
|
+
result = await this.authenticateManagedIdentity(scopes, updatedOptions);
|
|
2845
2887
|
if (result === null) {
|
|
2846
2888
|
// If authenticateManagedIdentity returns null,
|
|
2847
2889
|
// it means no MSI endpoints are available.
|
|
@@ -2929,14 +2971,12 @@ class ManagedIdentityCredential {
|
|
|
2929
2971
|
*/
|
|
2930
2972
|
class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
|
|
2931
2973
|
constructor(options) {
|
|
2932
|
-
var _a;
|
|
2933
|
-
const managedIdentityClientId = (_a = options === null ||
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
}
|
|
2937
|
-
|
|
2938
|
-
super(options);
|
|
2939
|
-
}
|
|
2974
|
+
var _a, _b, _c;
|
|
2975
|
+
const managedIdentityClientId = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
|
|
2976
|
+
const managedResourceId = (_c = options) === null || _c === void 0 ? void 0 : _c.managedIdentityResourceId;
|
|
2977
|
+
// ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
|
|
2978
|
+
const managedIdentityOptions = Object.assign({ resourceId: managedResourceId, clientId: managedIdentityClientId }, options);
|
|
2979
|
+
super(managedIdentityOptions);
|
|
2940
2980
|
}
|
|
2941
2981
|
}
|
|
2942
2982
|
const defaultCredentials = [
|