@azure/identity 2.0.0 → 2.0.1-alpha.20211025.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @azure/identity might be problematic. Click here for more details.

package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Release History
2
2
 
3
+ ## 2.0.1 (Unreleased)
4
+
5
+ ### Features Added
6
+
7
+ - The `ManagedIdentityCredential` now supports the Service Fabric environment.
8
+
9
+ ### Breaking Changes
10
+
11
+ ### Bugs Fixed
12
+
13
+ - Fixed a bug that caused the `AzureCliCredential` to fail on Windows. Issue [18268](https://github.com/Azure/azure-sdk-for-js/issues/18268).
14
+
15
+ ### Other Changes
16
+
3
17
  ## 2.0.0 (2021-10-15)
4
18
 
5
19
  After multiple beta releases over the past year, we're proud to announce the general availability of version 2 of the `@azure/identity` package. This version includes the best parts of v1, plus several improvements.
@@ -156,6 +170,15 @@ Identity v2 for JavaScript now also depends on the latest available versions of
156
170
 
157
171
  - The errors thrown by the `ManagedIdentityCredential` have been improved.
158
172
 
173
+ ## 1.5.2 (2021-09-01)
174
+
175
+ - Fixed a bug introduced on 1.5.0 that caused the `ManagedIdentityCredential` to fail authenticating in Arc environments. Since our new core disables unsafe requests by default, we had to change the security settings for the first request of the Arc MSI, which retrieves the file path where the authentication value is stored since this request generally happens through an HTTP endpoint.
176
+
177
+ ## 1.5.1 (2021-08-12)
178
+
179
+ - Fixed how we verify the IMDS endpoint is available. Now, besides skipping the `Metadata` header, we skip the URL query. Both will ensure that all the known IMDS endpoints return as early as possible.
180
+ - Added support for the `AZURE_POD_IDENTITY_AUTHORITY_HOST` environment variable. If present, the IMDS endpoint initial verification will be skipped.
181
+
159
182
  ## 2.0.0-beta.5 (2021-08-10)
160
183
 
161
184
  ### Features Added
@@ -175,15 +198,6 @@ Identity v2 for JavaScript now also depends on the latest available versions of
175
198
 
176
199
  - With this release, we've migrated from using `@azure/core-http` to `@azure/core-rest-pipeline` for the handling of HTTP requests. See [Azure Core v1 vs v2](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-rest-pipeline/documentation/core2.md) for more on the difference and benefits of the move. This removes our dependency on `node-fetch` and along with it issues we have seen in using this dependency in specific environments like Kubernetes pods.
177
200
 
178
- ## 1.5.2 (2021-09-01)
179
-
180
- - Fixed a bug introduced on 1.5.0 that caused the `ManagedIdentityCredential` to fail authenticating in Arc environments. Since our new core disables unsafe requests by default, we had to change the security settings for the first request of the Arc MSI, which retrieves the file path where the authentication value is stored since this request generally happens through an HTTP endpoint.
181
-
182
- ## 1.5.1 (2021-08-12)
183
-
184
- - Fixed how we verify the IMDS endpoint is available. Now, besides skipping the `Metadata` header, we skip the URL query. Both will ensure that all the known IMDS endpoints return as early as possible.
185
- - Added support for the `AZURE_POD_IDENTITY_AUTHORITY_HOST` environment variable. If present, the IMDS endpoint initial verification will be skipped.
186
-
187
201
  ## 1.5.0 (2021-07-19)
188
202
 
189
203
  - With this release, we've migrated from using `@azure/core-http` to `@azure/core-rest-pipeline` for the handling of HTTP requests. See [Azure Core v1 vs v2](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-rest-pipeline/documentation/core2.md) for more on the difference and benefits of the move. This removes our dependency on `node-fetch` and along with it issues we have seen in using this dependency in specific environments like Kubernetes pods.
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var coreTracing = require('@azure/core-tracing');
10
10
  var coreUtil = require('@azure/core-util');
11
11
  var coreRestPipeline = require('@azure/core-rest-pipeline');
12
12
  var abortController = require('@azure/abort-controller');
13
- var logger$j = require('@azure/logger');
13
+ var logger$k = require('@azure/logger');
14
14
  var msalCommon = require('@azure/msal-common');
15
15
  var uuid = require('uuid');
16
16
  var fs = require('fs');
@@ -21,6 +21,7 @@ var child_process = require('child_process');
21
21
  var child_process__default = _interopDefault(child_process);
22
22
  var crypto = require('crypto');
23
23
  var util = require('util');
24
+ var https = _interopDefault(require('https'));
24
25
  var http = _interopDefault(require('http'));
25
26
  var open = _interopDefault(require('open'));
26
27
  var stoppable = _interopDefault(require('stoppable'));
@@ -240,7 +241,7 @@ async function trace(operationName, options, fn, createSpanFn = createSpan) {
240
241
  /**
241
242
  * The AzureLogger used for all clients within the identity package
242
243
  */
243
- const logger = logger$j.createClientLogger("identity");
244
+ const logger = logger$k.createClientLogger("identity");
244
245
  /**
245
246
  * Separates a list of environment variable names into a plain object with two arrays: an array of missing environment variables and another array with assigned environment variables.
246
247
  * @param supportedEnvVars - List of environment variable names
@@ -331,7 +332,7 @@ function getIdentityClientAuthorityHost(options) {
331
332
  class IdentityClient extends coreClient.ServiceClient {
332
333
  constructor(options) {
333
334
  var _a;
334
- const packageDetails = `azsdk-js-identity/2.0.0`;
335
+ const packageDetails = `azsdk-js-identity/2.0.1`;
335
336
  const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
336
337
  ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
337
338
  : `${packageDetails}`;
@@ -1447,7 +1448,7 @@ const cliCredentialInternals = {
1447
1448
  "--resource",
1448
1449
  resource,
1449
1450
  ...tenantSection
1450
- ], { cwd: cliCredentialInternals.getSafeWorkingDir() }, (error, stdout, stderr) => {
1451
+ ], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true }, (error, stdout, stderr) => {
1451
1452
  resolve({ stdout: stdout, stderr: stderr, error });
1452
1453
  });
1453
1454
  }
@@ -2123,6 +2124,7 @@ const imdsHost = "http://169.254.169.254";
2123
2124
  const imdsEndpointPath = "/metadata/identity/oauth2/token";
2124
2125
  const imdsApiVersion = "2018-02-01";
2125
2126
  const azureArcAPIVersion = "2019-11-01";
2127
+ const azureFabricVersion = "2019-07-01-preview";
2126
2128
 
2127
2129
  // Copyright (c) Microsoft Corporation.
2128
2130
  /**
@@ -2149,8 +2151,11 @@ function mapScopesToResource(scopes) {
2149
2151
  }
2150
2152
  return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
2151
2153
  }
2152
- async function msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions = {}) {
2154
+ async function msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions = {}, agent) {
2153
2155
  const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, requestOptions), { allowInsecureConnection: true }));
2156
+ if (agent) {
2157
+ request.agent = agent;
2158
+ }
2154
2159
  const tokenResponse = await identityClient.sendTokenRequest(request, expiresInParser);
2155
2160
  return (tokenResponse && tokenResponse.accessToken) || null;
2156
2161
  }
@@ -2573,7 +2578,84 @@ function tokenExchangeMsi() {
2573
2578
  }
2574
2579
 
2575
2580
  // Copyright (c) Microsoft Corporation.
2576
- const logger$e = credentialLogger("ManagedIdentityCredential");
2581
+ const msiName$5 = "ManagedIdentityCredential - Fabric MSI";
2582
+ const logger$e = credentialLogger(msiName$5);
2583
+ function expiresInParser$5(requestBody) {
2584
+ // Parses a string representation of the seconds since epoch into a number value
2585
+ return Number(requestBody.expires_on);
2586
+ }
2587
+ function prepareRequestOptions$5(scopes, clientId) {
2588
+ const resource = mapScopesToResource(scopes);
2589
+ if (!resource) {
2590
+ throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
2591
+ }
2592
+ const queryParameters = {
2593
+ resource,
2594
+ "api-version": azureFabricVersion
2595
+ };
2596
+ if (clientId) {
2597
+ queryParameters.client_id = clientId;
2598
+ }
2599
+ const query = new URLSearchParams(queryParameters);
2600
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2601
+ if (!process.env.IDENTITY_ENDPOINT) {
2602
+ throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
2603
+ }
2604
+ if (!process.env.IDENTITY_HEADER) {
2605
+ throw new Error("Missing environment variable: IDENTITY_HEADER");
2606
+ }
2607
+ return {
2608
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
2609
+ method: "GET",
2610
+ headers: coreRestPipeline.createHttpHeaders({
2611
+ Accept: "application/json",
2612
+ Secret: process.env.IDENTITY_HEADER
2613
+ })
2614
+ };
2615
+ }
2616
+ // This credential can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
2617
+ //
2618
+ // FROM node:12
2619
+ // RUN wget https://host.any/path/bash.sh
2620
+ // CMD ["bash", "bash.sh"]
2621
+ //
2622
+ // Where the bash script contains:
2623
+ //
2624
+ // curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
2625
+ //
2626
+ const fabricMsi = {
2627
+ async isAvailable(scopes) {
2628
+ const resource = mapScopesToResource(scopes);
2629
+ if (!resource) {
2630
+ logger$e.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
2631
+ return false;
2632
+ }
2633
+ const env = process.env;
2634
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
2635
+ if (!result) {
2636
+ logger$e.info(`${msiName$5}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
2637
+ }
2638
+ return result;
2639
+ },
2640
+ async getToken(configuration, getTokenOptions = {}) {
2641
+ const { scopes, identityClient, clientId } = configuration;
2642
+ logger$e.info([
2643
+ `${msiName$5}:`,
2644
+ "Using the endpoint and the secret coming from the environment variables:",
2645
+ `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
2646
+ "IDENTITY_HEADER=[REDACTED] and",
2647
+ "IDENTITY_SERVER_THUMBPRINT=[REDACTED]."
2648
+ ].join(" "));
2649
+ return msiGenericGetToken(identityClient, prepareRequestOptions$5(scopes, clientId), expiresInParser$5, getTokenOptions, new https.Agent({
2650
+ // This is necessary because Service Fabric provides a self-signed certificate.
2651
+ // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
2652
+ rejectUnauthorized: false
2653
+ }));
2654
+ }
2655
+ };
2656
+
2657
+ // Copyright (c) Microsoft Corporation.
2658
+ const logger$f = credentialLogger("ManagedIdentityCredential");
2577
2659
  /**
2578
2660
  * Attempts authentication using a managed identity that has been assigned
2579
2661
  * to the deployment environment. This authentication type works in Azure VMs,
@@ -2604,9 +2686,7 @@ class ManagedIdentityCredential {
2604
2686
  if (this.cachedMSI) {
2605
2687
  return this.cachedMSI;
2606
2688
  }
2607
- // "fabricMsi" can't be added yet because our HTTPs pipeline doesn't allow skipping the SSL verification step,
2608
- // which is necessary since Service Fabric only provides self-signed certificates on their Identity Endpoint.
2609
- const MSIs = [appServiceMsi2017, cloudShellMsi, arcMsi, tokenExchangeMsi(), imdsMsi];
2689
+ const MSIs = [fabricMsi, appServiceMsi2017, cloudShellMsi, arcMsi, tokenExchangeMsi(), imdsMsi];
2610
2690
  for (const msi of MSIs) {
2611
2691
  if (await msi.isAvailable(scopes, this.identityClient, clientId, getTokenOptions)) {
2612
2692
  this.cachedMSI = msi;
@@ -2663,7 +2743,7 @@ class ManagedIdentityCredential {
2663
2743
  // It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
2664
2744
  // yet we had no access token. For this reason, we'll throw once with a specific message:
2665
2745
  const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
2666
- logger$e.getToken.info(formatError(scopes, error));
2746
+ logger$f.getToken.info(formatError(scopes, error));
2667
2747
  throw error;
2668
2748
  }
2669
2749
  // Since `authenticateManagedIdentity` didn't throw, and the result was not null,
@@ -2675,10 +2755,10 @@ class ManagedIdentityCredential {
2675
2755
  // We've previously determined that the endpoint was unavailable,
2676
2756
  // either because it was unreachable or permanently unable to authenticate.
2677
2757
  const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
2678
- logger$e.getToken.info(formatError(scopes, error));
2758
+ logger$f.getToken.info(formatError(scopes, error));
2679
2759
  throw error;
2680
2760
  }
2681
- logger$e.getToken.info(formatSuccess(scopes));
2761
+ logger$f.getToken.info(formatSuccess(scopes));
2682
2762
  return result;
2683
2763
  }
2684
2764
  catch (err) {
@@ -2700,14 +2780,14 @@ class ManagedIdentityCredential {
2700
2780
  // we can safely assume the credential is unavailable.
2701
2781
  if (err.code === "ENETUNREACH") {
2702
2782
  const error = new CredentialUnavailableError(`ManagedIdentityCredential is unavailable. Network unreachable. Message: ${err.message}`);
2703
- logger$e.getToken.info(formatError(scopes, error));
2783
+ logger$f.getToken.info(formatError(scopes, error));
2704
2784
  throw error;
2705
2785
  }
2706
2786
  // If either the host was unreachable,
2707
2787
  // we can safely assume the credential is unavailable.
2708
2788
  if (err.code === "EHOSTUNREACH") {
2709
2789
  const error = new CredentialUnavailableError(`ManagedIdentityCredential is unavailable. No managed identity endpoint found. Message: ${err.message}`);
2710
- logger$e.getToken.info(formatError(scopes, error));
2790
+ logger$f.getToken.info(formatError(scopes, error));
2711
2791
  throw error;
2712
2792
  }
2713
2793
  // If err.statusCode has a value of 400, it comes from sendTokenRequest,
@@ -2939,7 +3019,7 @@ class MsalOpenBrowser extends MsalNode {
2939
3019
  }
2940
3020
 
2941
3021
  // Copyright (c) Microsoft Corporation.
2942
- const logger$f = credentialLogger("InteractiveBrowserCredential");
3022
+ const logger$g = credentialLogger("InteractiveBrowserCredential");
2943
3023
  /**
2944
3024
  * Enables authentication to Azure Active Directory inside of the web browser
2945
3025
  * using the interactive login flow.
@@ -2961,7 +3041,7 @@ class InteractiveBrowserCredential {
2961
3041
  const redirectUri = typeof options.redirectUri === "function"
2962
3042
  ? options.redirectUri()
2963
3043
  : options.redirectUri || "http://localhost";
2964
- this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger: logger$f,
3044
+ this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger: logger$g,
2965
3045
  redirectUri }));
2966
3046
  this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
2967
3047
  }
@@ -3039,7 +3119,7 @@ class MsalDeviceCode extends MsalNode {
3039
3119
  }
3040
3120
 
3041
3121
  // Copyright (c) Microsoft Corporation.
3042
- const logger$g = credentialLogger("DeviceCodeCredential");
3122
+ const logger$h = credentialLogger("DeviceCodeCredential");
3043
3123
  /**
3044
3124
  * Method that logs the user code from the DeviceCodeCredential.
3045
3125
  * @param deviceCodeInfo - The device code.
@@ -3073,7 +3153,7 @@ class DeviceCodeCredential {
3073
3153
  * @param options - Options for configuring the client which makes the authentication requests.
3074
3154
  */
3075
3155
  constructor(options) {
3076
- this.msalFlow = new MsalDeviceCode(Object.assign(Object.assign({}, options), { logger: logger$g, userPromptCallback: (options === null || options === void 0 ? void 0 : options.userPromptCallback) || defaultDeviceCodePromptCallback, tokenCredentialOptions: options || {} }));
3156
+ this.msalFlow = new MsalDeviceCode(Object.assign(Object.assign({}, options), { logger: logger$h, userPromptCallback: (options === null || options === void 0 ? void 0 : options.userPromptCallback) || defaultDeviceCodePromptCallback, tokenCredentialOptions: options || {} }));
3077
3157
  this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
3078
3158
  }
3079
3159
  /**
@@ -3152,7 +3232,7 @@ class MsalAuthorizationCode extends MsalNode {
3152
3232
  }
3153
3233
 
3154
3234
  // Copyright (c) Microsoft Corporation.
3155
- const logger$h = credentialLogger("AuthorizationCodeCredential");
3235
+ const logger$i = credentialLogger("AuthorizationCodeCredential");
3156
3236
  /**
3157
3237
  * Enables authentication to Azure Active Directory using an authorization code
3158
3238
  * that was obtained through the authorization code flow, described in more detail
@@ -3166,7 +3246,7 @@ class AuthorizationCodeCredential {
3166
3246
  * @internal
3167
3247
  */
3168
3248
  constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
3169
- checkTenantId(logger$h, tenantId);
3249
+ checkTenantId(logger$i, tenantId);
3170
3250
  let clientSecret = clientSecretOrAuthorizationCode;
3171
3251
  if (typeof redirectUriOrOptions === "string") {
3172
3252
  // the clientId+clientSecret constructor
@@ -3182,7 +3262,7 @@ class AuthorizationCodeCredential {
3182
3262
  options = redirectUriOrOptions;
3183
3263
  }
3184
3264
  this.msalFlow = new MsalAuthorizationCode(Object.assign(Object.assign({}, options), { clientSecret,
3185
- clientId, tokenCredentialOptions: options || {}, logger: logger$h, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
3265
+ clientId, tokenCredentialOptions: options || {}, logger: logger$i, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
3186
3266
  }
3187
3267
  /**
3188
3268
  * Authenticates with Azure Active Directory and returns an access token if successful.
@@ -3254,7 +3334,7 @@ class MsalOnBehalfOf extends MsalNode {
3254
3334
 
3255
3335
  // Copyright (c) Microsoft Corporation.
3256
3336
  const credentialName$1 = "OnBehalfOfCredential";
3257
- const logger$i = credentialLogger(credentialName$1);
3337
+ const logger$j = credentialLogger(credentialName$1);
3258
3338
  /**
3259
3339
  * Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
3260
3340
  */
@@ -3288,7 +3368,7 @@ class OnBehalfOfCredential {
3288
3368
  if (!tenantId || !clientId || !(clientSecret || certificatePath) || !userAssertionToken) {
3289
3369
  throw new Error(`${credentialName$1}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`);
3290
3370
  }
3291
- this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger: logger$i, tokenCredentialOptions: this.options }));
3371
+ this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger: logger$j, tokenCredentialOptions: this.options }));
3292
3372
  }
3293
3373
  /**
3294
3374
  * Authenticates with Azure Active Directory and returns an access token if successful.