@azure/identity 1.3.0 → 1.5.2

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.

Files changed (54) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +8 -1
  3. package/dist/index.js +233 -168
  4. package/dist/index.js.map +1 -1
  5. package/dist-esm/src/client/identityClient.js +92 -51
  6. package/dist-esm/src/client/identityClient.js.map +1 -1
  7. package/dist-esm/src/client/msalClient.js.map +1 -1
  8. package/dist-esm/src/constants.js +5 -0
  9. package/dist-esm/src/constants.js.map +1 -1
  10. package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
  11. package/dist-esm/src/credentials/authorizationCodeCredential.js +8 -7
  12. package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
  13. package/dist-esm/src/credentials/azureCliCredential.browser.js.map +1 -1
  14. package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
  15. package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
  16. package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
  17. package/dist-esm/src/credentials/clientCertificateCredential.js +8 -7
  18. package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
  19. package/dist-esm/src/credentials/clientSecretCredential.js +10 -9
  20. package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
  21. package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
  22. package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
  23. package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
  24. package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
  25. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +2 -3
  26. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
  27. package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
  28. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +11 -5
  29. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
  30. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +16 -9
  31. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
  32. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +4 -3
  33. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
  34. package/dist-esm/src/credentials/managedIdentityCredential/constants.js +2 -1
  35. package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -1
  36. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +6 -4
  37. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
  38. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +42 -21
  39. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
  40. package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -1
  41. package/dist-esm/src/credentials/managedIdentityCredential/index.js +1 -1
  42. package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
  43. package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
  44. package/dist-esm/src/credentials/managedIdentityCredential/utils.js +6 -2
  45. package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -1
  46. package/dist-esm/src/credentials/usernamePasswordCredential.js +8 -7
  47. package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
  48. package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -1
  49. package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
  50. package/dist-esm/src/index.js.map +1 -1
  51. package/dist-esm/src/util/isNode.js +10 -0
  52. package/dist-esm/src/util/isNode.js.map +1 -0
  53. package/package.json +6 -7
  54. package/types/identity.d.ts +7 -6
package/dist/index.js CHANGED
@@ -8,7 +8,8 @@ var tslib = require('tslib');
8
8
  var coreTracing = require('@azure/core-tracing');
9
9
  var logger$h = require('@azure/logger');
10
10
  var qs = _interopDefault(require('qs'));
11
- var coreHttp = require('@azure/core-http');
11
+ var coreRestPipeline = require('@azure/core-rest-pipeline');
12
+ var coreClient = require('@azure/core-client');
12
13
  var jws = _interopDefault(require('jws'));
13
14
  var uuid = require('uuid');
14
15
  var fs = require('fs');
@@ -274,19 +275,6 @@ class ChainedTokenCredential {
274
275
  }
275
276
  }
276
277
 
277
- // Copyright (c) Microsoft Corporation.
278
- // Licensed under the MIT license.
279
- function getAuthorityHostEnvironment() {
280
- if (process.env.AZURE_AUTHORITY_HOST) {
281
- return {
282
- authorityHost: process.env.AZURE_AUTHORITY_HOST
283
- };
284
- }
285
- else {
286
- return undefined;
287
- }
288
- }
289
-
290
278
  // Copyright (c) Microsoft Corporation.
291
279
  // Licensed under the MIT license.
292
280
  function getIdentityTokenEndpointSuffix(tenantId) {
@@ -299,62 +287,132 @@ function getIdentityTokenEndpointSuffix(tenantId) {
299
287
  }
300
288
 
301
289
  // Copyright (c) Microsoft Corporation.
302
- const DefaultAuthorityHost = "https://login.microsoftonline.com";
303
- class IdentityClient extends coreHttp.ServiceClient {
290
+ // Licensed under the MIT license.
291
+ /**
292
+ * The default client ID for authentication
293
+ * @internal
294
+ */
295
+ // TODO: temporary - this is the Azure CLI clientID - we'll replace it when
296
+ // Developer Sign On application is available
297
+ // https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/src/Constants.cs#L9
298
+ const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
299
+ /**
300
+ * The default tenant for authentication
301
+ * @internal
302
+ */
303
+ const DefaultTenantId = "common";
304
+ (function (AzureAuthorityHosts) {
305
+ /**
306
+ * China-based Azure Authority Host
307
+ */
308
+ AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
309
+ /**
310
+ * Germany-based Azure Authority Host
311
+ */
312
+ AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
313
+ /**
314
+ * US Government Azure Authority Host
315
+ */
316
+ AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
317
+ /**
318
+ * Public Cloud Azure Authority Host
319
+ */
320
+ AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
321
+ })(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
322
+ /**
323
+ * The default authority host.
324
+ * @internal
325
+ */
326
+ const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
327
+
328
+ // Copyright (c) Microsoft Corporation.
329
+ /**
330
+ * Safe JSON parse.
331
+ * @internal
332
+ */
333
+ function parse(input) {
334
+ if (!input) {
335
+ return {};
336
+ }
337
+ try {
338
+ return JSON.parse(input);
339
+ }
340
+ catch (e) {
341
+ return {};
342
+ }
343
+ }
344
+ /**
345
+ * @internal
346
+ */
347
+ function getIdentityClientAuthorityHost(options) {
348
+ // The authorityHost can come from options or from the AZURE_AUTHORITY_HOST environment variable.
349
+ let authorityHost = options === null || options === void 0 ? void 0 : options.authorityHost;
350
+ // The AZURE_AUTHORITY_HOST environment variable can only be provided in NodeJS.
351
+ {
352
+ authorityHost = authorityHost !== null && authorityHost !== void 0 ? authorityHost : process.env.AZURE_AUTHORITY_HOST;
353
+ }
354
+ // If the authorityHost is not provided, we use the default one from the public cloud: https://login.microsoftonline.com
355
+ return authorityHost !== null && authorityHost !== void 0 ? authorityHost : DefaultAuthorityHost;
356
+ }
357
+ /**
358
+ * The network module used by the Identity credentials.
359
+ *
360
+ * It allows for credentials to abort any pending request independently of the MSAL flow,
361
+ * by calling to the `abortRequests()` method.
362
+ *
363
+ */
364
+ class IdentityClient extends coreClient.ServiceClient {
304
365
  constructor(options) {
305
- {
306
- options = options || getAuthorityHostEnvironment();
307
- }
308
- options = options || IdentityClient.getDefaultOptions();
309
- super(undefined, coreHttp.createPipelineFromOptions(Object.assign(Object.assign({}, options), { deserializationOptions: {
310
- expectedContentTypes: {
311
- json: ["application/json", "text/json", "text/plain"]
312
- }
313
- } })));
314
- this.baseUri = this.authorityHost = options.authorityHost || DefaultAuthorityHost;
315
- if (!this.baseUri.startsWith("https:")) {
366
+ var _a;
367
+ const packageDetails = `azsdk-js-identity/1.5.2`;
368
+ const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix) ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
369
+ : `${packageDetails}`;
370
+ const baseUri = getIdentityClientAuthorityHost(options);
371
+ if (!baseUri.startsWith("https:")) {
316
372
  throw new Error("The authorityHost address must use the 'https' protocol.");
317
373
  }
374
+ super(Object.assign(Object.assign({ requestContentType: "application/json; charset=utf-8" }, options), { userAgentOptions: {
375
+ userAgentPrefix
376
+ }, baseUri }));
377
+ this.authorityHost = baseUri;
318
378
  }
319
- createWebResource(requestOptions) {
320
- const webResource = new coreHttp.WebResource();
321
- webResource.prepare(requestOptions);
322
- return webResource;
323
- }
324
- sendTokenRequest(webResource, expiresOnParser) {
379
+ sendTokenRequest(request, expiresOnParser) {
380
+ var _a;
325
381
  return tslib.__awaiter(this, void 0, void 0, function* () {
326
- logger.info(`IdentityClient: sending token request to [${webResource.url}]`);
327
- const response = yield this.sendRequest(webResource);
382
+ logger.info(`IdentityClient: sending token request to [${request.url}]`);
383
+ const response = yield this.sendRequest(request);
328
384
  expiresOnParser =
329
385
  expiresOnParser ||
330
386
  ((responseBody) => {
331
387
  return Date.now() + responseBody.expires_in * 1000;
332
388
  });
333
- if (response.status === 200 || response.status === 201) {
389
+ if (response.bodyAsText && (response.status === 200 || response.status === 201)) {
390
+ const parsedBody = parse(response.bodyAsText);
334
391
  const token = {
335
392
  accessToken: {
336
- token: response.parsedBody.access_token,
337
- expiresOnTimestamp: expiresOnParser(response.parsedBody)
393
+ token: (_a = parsedBody.token) !== null && _a !== void 0 ? _a : parsedBody.access_token,
394
+ expiresOnTimestamp: expiresOnParser(parsedBody)
338
395
  },
339
- refreshToken: response.parsedBody.refresh_token
396
+ refreshToken: parsedBody.refresh_token
340
397
  };
341
- logger.info(`IdentityClient: [${webResource.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
398
+ logger.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
342
399
  return token;
343
400
  }
344
401
  else {
345
- const error = new AuthenticationError(response.status, response.parsedBody || response.bodyAsText);
402
+ const error = new AuthenticationError(response.status, response.bodyAsText);
346
403
  logger.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
347
404
  throw error;
348
405
  }
349
406
  });
350
407
  }
351
408
  refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, expiresOnParser, options) {
409
+ var _a, _b;
352
410
  return tslib.__awaiter(this, void 0, void 0, function* () {
353
411
  if (refreshToken === undefined) {
354
412
  return null;
355
413
  }
356
414
  logger.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
357
- const { span, updatedOptions: newOptions } = createSpan("IdentityClient-refreshAccessToken", options);
415
+ const { span, updatedOptions } = createSpan("IdentityClient-refreshAccessToken", options);
358
416
  const refreshParams = {
359
417
  grant_type: "refresh_token",
360
418
  client_id: clientId,
@@ -366,19 +424,19 @@ class IdentityClient extends coreHttp.ServiceClient {
366
424
  }
367
425
  try {
368
426
  const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);
369
- const webResource = this.createWebResource({
427
+ const webResource = coreRestPipeline.createPipelineRequest({
370
428
  url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,
371
429
  method: "POST",
372
- disableJsonStringifyOnBody: true,
373
- deserializationMapper: undefined,
374
430
  body: qs.stringify(refreshParams),
375
- headers: {
431
+ abortSignal: options && options.abortSignal,
432
+ headers: coreRestPipeline.createHttpHeaders({
376
433
  Accept: "application/json",
377
434
  "Content-Type": "application/x-www-form-urlencoded"
378
- },
379
- spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
380
- tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext,
381
- abortSignal: options && options.abortSignal
435
+ }),
436
+ tracingOptions: {
437
+ spanOptions: (_a = updatedOptions === null || updatedOptions === void 0 ? void 0 : updatedOptions.tracingOptions) === null || _a === void 0 ? void 0 : _a.spanOptions,
438
+ tracingContext: (_b = updatedOptions === null || updatedOptions === void 0 ? void 0 : updatedOptions.tracingOptions) === null || _b === void 0 ? void 0 : _b.tracingContext
439
+ }
382
440
  });
383
441
  const response = yield this.sendTokenRequest(webResource, expiresOnParser);
384
442
  logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
@@ -411,31 +469,39 @@ class IdentityClient extends coreHttp.ServiceClient {
411
469
  }
412
470
  });
413
471
  }
472
+ // The MSAL network module methods follow
414
473
  sendGetRequestAsync(url, options) {
415
- const webResource = new coreHttp.WebResource(url, "GET", options === null || options === void 0 ? void 0 : options.body, {}, options === null || options === void 0 ? void 0 : options.headers);
416
- return this.sendRequest(webResource).then((response) => {
474
+ return tslib.__awaiter(this, void 0, void 0, function* () {
475
+ const request = coreRestPipeline.createPipelineRequest({
476
+ url,
477
+ method: "GET",
478
+ body: options === null || options === void 0 ? void 0 : options.body,
479
+ headers: coreRestPipeline.createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers)
480
+ });
481
+ const response = yield this.sendRequest(request);
417
482
  return {
418
- body: response.parsedBody,
419
- headers: response.headers.rawHeaders(),
483
+ body: parse(response.bodyAsText),
484
+ headers: response.headers.toJSON(),
420
485
  status: response.status
421
486
  };
422
487
  });
423
488
  }
424
489
  sendPostRequestAsync(url, options) {
425
- const webResource = new coreHttp.WebResource(url, "POST", options === null || options === void 0 ? void 0 : options.body, {}, options === null || options === void 0 ? void 0 : options.headers);
426
- return this.sendRequest(webResource).then((response) => {
490
+ return tslib.__awaiter(this, void 0, void 0, function* () {
491
+ const request = coreRestPipeline.createPipelineRequest({
492
+ url,
493
+ method: "POST",
494
+ body: options === null || options === void 0 ? void 0 : options.body,
495
+ headers: coreRestPipeline.createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers)
496
+ });
497
+ const response = yield this.sendRequest(request);
427
498
  return {
428
- body: response.parsedBody,
429
- headers: response.headers.rawHeaders(),
499
+ body: parse(response.bodyAsText),
500
+ headers: response.headers.toJSON(),
430
501
  status: response.status
431
502
  };
432
503
  });
433
504
  }
434
- static getDefaultOptions() {
435
- return {
436
- authorityHost: DefaultAuthorityHost
437
- };
438
- }
439
505
  }
440
506
 
441
507
  // Copyright (c) Microsoft Corporation.
@@ -477,14 +543,12 @@ class ClientSecretCredential {
477
543
  */
478
544
  getToken(scopes, options) {
479
545
  return tslib.__awaiter(this, void 0, void 0, function* () {
480
- const { span, updatedOptions: newOptions } = createSpan("ClientSecretCredential-getToken", options);
546
+ const { span, updatedOptions } = createSpan("ClientSecretCredential-getToken", options);
481
547
  try {
482
548
  const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
483
- const webResource = this.identityClient.createWebResource({
549
+ const request = coreRestPipeline.createPipelineRequest({
484
550
  url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
485
551
  method: "POST",
486
- disableJsonStringifyOnBody: true,
487
- deserializationMapper: undefined,
488
552
  body: qs.stringify({
489
553
  response_type: "token",
490
554
  grant_type: "client_credentials",
@@ -492,15 +556,17 @@ class ClientSecretCredential {
492
556
  client_secret: this.clientSecret,
493
557
  scope: typeof scopes === "string" ? scopes : scopes.join(" ")
494
558
  }),
495
- headers: {
559
+ headers: coreRestPipeline.createHttpHeaders({
496
560
  Accept: "application/json",
497
561
  "Content-Type": "application/x-www-form-urlencoded"
498
- },
562
+ }),
499
563
  abortSignal: options && options.abortSignal,
500
- spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
501
- tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext,
564
+ tracingOptions: {
565
+ spanOptions: updatedOptions.tracingOptions && updatedOptions.tracingOptions.spanOptions,
566
+ tracingContext: updatedOptions.tracingOptions && updatedOptions.tracingOptions.tracingContext
567
+ }
502
568
  });
503
- const tokenResponse = yield this.identityClient.sendTokenRequest(webResource);
569
+ const tokenResponse = yield this.identityClient.sendTokenRequest(request);
504
570
  logger$2.getToken.info(formatSuccess(scopes));
505
571
  return (tokenResponse && tokenResponse.accessToken) || null;
506
572
  }
@@ -632,11 +698,9 @@ class ClientCertificateCredential {
632
698
  payload,
633
699
  secret: this.certificateString
634
700
  });
635
- const webResource = this.identityClient.createWebResource({
701
+ const webResource = coreRestPipeline.createPipelineRequest({
636
702
  url: audienceUrl,
637
703
  method: "POST",
638
- disableJsonStringifyOnBody: true,
639
- deserializationMapper: undefined,
640
704
  body: qs.stringify({
641
705
  response_type: "token",
642
706
  grant_type: "client_credentials",
@@ -645,13 +709,15 @@ class ClientCertificateCredential {
645
709
  client_assertion: clientAssertion,
646
710
  scope: typeof scopes === "string" ? scopes : scopes.join(" ")
647
711
  }),
648
- headers: {
712
+ headers: coreRestPipeline.createHttpHeaders({
649
713
  Accept: "application/json",
650
714
  "Content-Type": "application/x-www-form-urlencoded"
651
- },
715
+ }),
652
716
  abortSignal: options && options.abortSignal,
653
- spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
654
- tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext,
717
+ tracingOptions: {
718
+ spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
719
+ tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext
720
+ }
655
721
  });
656
722
  const tokenResponse = yield this.identityClient.sendTokenRequest(webResource);
657
723
  logger$3.getToken.info(formatSuccess(scopes));
@@ -715,11 +781,9 @@ class UsernamePasswordCredential {
715
781
  const { span, updatedOptions: newOptions } = createSpan("UsernamePasswordCredential-getToken", options);
716
782
  try {
717
783
  const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
718
- const webResource = this.identityClient.createWebResource({
784
+ const webResource = coreRestPipeline.createPipelineRequest({
719
785
  url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
720
786
  method: "POST",
721
- disableJsonStringifyOnBody: true,
722
- deserializationMapper: undefined,
723
787
  body: qs.stringify({
724
788
  response_type: "token",
725
789
  grant_type: "password",
@@ -728,13 +792,15 @@ class UsernamePasswordCredential {
728
792
  password: this.password,
729
793
  scope: typeof scopes === "string" ? scopes : scopes.join(" ")
730
794
  }),
731
- headers: {
795
+ headers: coreRestPipeline.createHttpHeaders({
732
796
  Accept: "application/json",
733
797
  "Content-Type": "application/x-www-form-urlencoded"
734
- },
798
+ }),
735
799
  abortSignal: options && options.abortSignal,
736
- spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
737
- tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext,
800
+ tracingOptions: {
801
+ spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
802
+ tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext
803
+ }
738
804
  });
739
805
  const tokenResponse = yield this.identityClient.sendTokenRequest(webResource);
740
806
  logger$4.getToken.info(formatSuccess(scopes));
@@ -872,7 +938,8 @@ class EnvironmentCredential {
872
938
  // Copyright (c) Microsoft Corporation.
873
939
  // Licensed under the MIT license.
874
940
  const DefaultScopeSuffix = "/.default";
875
- const imdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";
941
+ const imdsHost = "http://169.254.169.254";
942
+ const imdsEndpointPath = "/metadata/identity/oauth2/token";
876
943
  const imdsApiVersion = "2018-02-01";
877
944
  const azureArcAPIVersion = "2019-11-01";
878
945
 
@@ -895,8 +962,11 @@ function mapScopesToResource(scopes) {
895
962
  }
896
963
  function msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions = {}) {
897
964
  return tslib.__awaiter(this, void 0, void 0, function* () {
898
- const webResource = identityClient.createWebResource(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions, tracingContext: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.tracingContext }, requestOptions));
899
- const tokenResponse = yield identityClient.sendTokenRequest(webResource, expiresInParser);
965
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal, tracingOptions: {
966
+ spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions,
967
+ tracingContext: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.tracingContext
968
+ } }, requestOptions), { allowInsecureConnection: true }));
969
+ const tokenResponse = yield identityClient.sendTokenRequest(request, expiresInParser);
900
970
  return (tokenResponse && tokenResponse.accessToken) || null;
901
971
  });
902
972
  }
@@ -916,11 +986,11 @@ function prepareRequestOptions(resource, clientId) {
916
986
  url: process.env.MSI_ENDPOINT,
917
987
  method: "POST",
918
988
  body: qs.stringify(body),
919
- headers: {
989
+ headers: coreRestPipeline.createHttpHeaders({
920
990
  Accept: "application/json",
921
- Metadata: true,
991
+ Metadata: "true",
922
992
  "Content-Type": "application/x-www-form-urlencoded"
923
- }
993
+ })
924
994
  };
925
995
  }
926
996
  const cloudShellMsi = {
@@ -953,7 +1023,8 @@ function expiresInParser$1(requestBody) {
953
1023
  return expires;
954
1024
  }
955
1025
  }
956
- function prepareRequestOptions$1(resource, clientId) {
1026
+ function prepareRequestOptions$1(resource, clientId, options) {
1027
+ var _a;
957
1028
  const queryParameters = {
958
1029
  resource,
959
1030
  "api-version": imdsApiVersion
@@ -961,41 +1032,60 @@ function prepareRequestOptions$1(resource, clientId) {
961
1032
  if (clientId) {
962
1033
  queryParameters.client_id = clientId;
963
1034
  }
1035
+ const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
1036
+ const { skipQuery, skipMetadataHeader } = options || {};
1037
+ // Pod Identity will try to process this request even if the Metadata header is missing.
1038
+ // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
1039
+ let query = "";
1040
+ if (!skipQuery) {
1041
+ query = `?${qs.stringify(queryParameters)}`;
1042
+ }
1043
+ const headersSource = {
1044
+ Accept: "application/json",
1045
+ Metadata: "true"
1046
+ };
1047
+ // Remove the Metadata header to invoke a request error from some IMDS endpoints.
1048
+ if (skipMetadataHeader) {
1049
+ delete headersSource.Metadata;
1050
+ }
964
1051
  return {
965
- url: imdsEndpoint,
1052
+ url: `${url}${query}`,
966
1053
  method: "GET",
967
- queryParameters,
968
- headers: {
969
- Accept: "application/json",
970
- Metadata: true
971
- }
1054
+ headers: coreRestPipeline.createHttpHeaders(headersSource)
972
1055
  };
973
1056
  }
974
1057
  const imdsMsi = {
975
1058
  isAvailable(identityClient, resource, clientId, getTokenOptions) {
1059
+ var _a, _b;
976
1060
  return tslib.__awaiter(this, void 0, void 0, function* () {
977
- const { span, updatedOptions: options } = createSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions);
978
- const request = prepareRequestOptions$1(resource, clientId);
979
- // This will always be populated, but let's make TypeScript happy
980
- if (request.headers) {
981
- // Remove the Metadata header to invoke a request error from
982
- // IMDS endpoint
983
- delete request.headers.Metadata;
1061
+ // if the PodIdenityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
1062
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1063
+ return true;
984
1064
  }
985
- request.spanOptions = options.tracingOptions && options.tracingOptions.spanOptions;
986
- request.tracingContext = options.tracingOptions && options.tracingOptions.tracingContext;
1065
+ const { span, updatedOptions: options } = createSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions);
987
1066
  try {
988
1067
  // Create a request with a timeout since we expect that
989
1068
  // not having a "Metadata" header should cause an error to be
990
1069
  // returned quickly from the endpoint, proving its availability.
991
- const webResource = identityClient.createWebResource(request);
992
- webResource.timeout = (options.requestOptions && options.requestOptions.timeout) || 500;
1070
+ // Later we found that skipping the query parameters is also necessary in some cases.
1071
+ const requestOptions = prepareRequestOptions$1(resource, clientId, {
1072
+ skipMetadataHeader: true,
1073
+ skipQuery: true
1074
+ });
1075
+ requestOptions.tracingOptions = {
1076
+ spanOptions: options.tracingOptions && options.tracingOptions.spanOptions,
1077
+ tracingContext: options.tracingOptions && options.tracingOptions.tracingContext
1078
+ };
1079
+ const request = coreRestPipeline.createPipelineRequest(requestOptions);
1080
+ request.timeout = (_b = (_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) !== null && _b !== void 0 ? _b : 300;
1081
+ // This MSI uses the imdsEndpoint to get the token, which only uses http://
1082
+ request.allowInsecureConnection = true;
993
1083
  try {
994
1084
  logger$7.info(`Pinging IMDS endpoint`);
995
- yield identityClient.sendRequest(webResource);
1085
+ yield identityClient.sendRequest(request);
996
1086
  }
997
1087
  catch (err) {
998
- if ((err instanceof coreHttp.RestError && err.code === coreHttp.RestError.REQUEST_SEND_ERROR) ||
1088
+ if ((err instanceof coreRestPipeline.RestError && err.code === coreRestPipeline.RestError.REQUEST_SEND_ERROR) ||
999
1089
  err.name === "AbortError" ||
1000
1090
  err.code === "ECONNREFUSED" || // connection refused
1001
1091
  err.code === "EHOSTDOWN" // host is down
@@ -1054,21 +1144,25 @@ function prepareRequestOptions$2(resource, clientId) {
1054
1144
  if (clientId) {
1055
1145
  queryParameters.clientid = clientId;
1056
1146
  }
1147
+ const query = qs.stringify(queryParameters);
1057
1148
  return {
1058
- url: process.env.MSI_ENDPOINT,
1149
+ url: `${process.env.MSI_ENDPOINT}?${query}`,
1059
1150
  method: "GET",
1060
- queryParameters,
1061
- headers: {
1151
+ headers: coreRestPipeline.createHttpHeaders({
1062
1152
  Accept: "application/json",
1063
1153
  secret: process.env.MSI_SECRET
1064
- }
1154
+ })
1065
1155
  };
1066
1156
  }
1067
1157
  const appServiceMsi2017 = {
1068
1158
  isAvailable() {
1069
1159
  return tslib.__awaiter(this, void 0, void 0, function* () {
1070
1160
  const env = process.env;
1071
- return Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
1161
+ const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
1162
+ if (!result) {
1163
+ logger$8.info("The Azure App Service MSI 2017 is unavailable.");
1164
+ }
1165
+ return result;
1072
1166
  });
1073
1167
  },
1074
1168
  getToken(identityClient, resource, clientId, getTokenOptions = {}) {
@@ -1088,15 +1182,15 @@ function prepareRequestOptions$3(resource) {
1088
1182
  resource,
1089
1183
  "api-version": azureArcAPIVersion
1090
1184
  };
1185
+ const query = qs.stringify(queryParameters);
1091
1186
  return {
1092
1187
  // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
1093
- url: process.env.IDENTITY_ENDPOINT,
1188
+ url: `${process.env.IDENTITY_ENDPOINT}?${query}`,
1094
1189
  method: "GET",
1095
- queryParameters,
1096
- headers: {
1190
+ headers: coreRestPipeline.createHttpHeaders({
1097
1191
  Accept: "application/json",
1098
- Metadata: true
1099
- }
1192
+ Metadata: "true"
1193
+ })
1100
1194
  };
1101
1195
  }
1102
1196
  // Since "fs"'s readFileSync locks the thread, and to avoid extra dependencies.
@@ -1110,7 +1204,7 @@ function readFileAsync(path, options) {
1110
1204
  }
1111
1205
  function filePathRequest(identityClient, requestPrepareOptions) {
1112
1206
  return tslib.__awaiter(this, void 0, void 0, function* () {
1113
- const response = yield identityClient.sendRequest(identityClient.createWebResource(requestPrepareOptions));
1207
+ const response = yield identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
1114
1208
  if (response.status !== 401) {
1115
1209
  let message = "";
1116
1210
  if (response.bodyAsText) {
@@ -1125,22 +1219,27 @@ function filePathRequest(identityClient, requestPrepareOptions) {
1125
1219
  const arcMsi = {
1126
1220
  isAvailable() {
1127
1221
  return tslib.__awaiter(this, void 0, void 0, function* () {
1128
- return Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
1222
+ const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
1223
+ if (!result) {
1224
+ logger$9.info("The Azure Arc MSI is unavailable.");
1225
+ }
1226
+ return result;
1129
1227
  });
1130
1228
  },
1131
1229
  getToken(identityClient, resource, clientId, getTokenOptions = {}) {
1230
+ var _a;
1132
1231
  return tslib.__awaiter(this, void 0, void 0, function* () {
1133
1232
  logger$9.info(`Using the Azure Arc MSI to authenticate.`);
1134
1233
  if (clientId) {
1135
1234
  throw new Error("User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.");
1136
1235
  }
1137
- const requestOptions = Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions, tracingContext: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.tracingContext }, prepareRequestOptions$3(resource));
1236
+ const requestOptions = Object.assign({ allowInsecureConnection: true, disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions }, prepareRequestOptions$3(resource));
1138
1237
  const filePath = yield filePathRequest(identityClient, requestOptions);
1139
1238
  if (!filePath) {
1140
1239
  throw new Error("Azure Arc MSI failed to find the token file.");
1141
1240
  }
1142
1241
  const key = yield readFileAsync(filePath, { encoding: "utf-8" });
1143
- requestOptions.headers["Authorization"] = `Basic ${key}`;
1242
+ (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
1144
1243
  return msiGenericGetToken(identityClient, requestOptions, expiresInParser$3, getTokenOptions);
1145
1244
  });
1146
1245
  }
@@ -1167,7 +1266,7 @@ class ManagedIdentityCredential {
1167
1266
  if (typeof clientIdOrOptions === "string") {
1168
1267
  // clientId, options constructor
1169
1268
  this.clientId = clientIdOrOptions;
1170
- this.identityClient = new IdentityClient(options);
1269
+ this.identityClient = new IdentityClient(Object.assign({}, options));
1171
1270
  }
1172
1271
  else {
1173
1272
  // options only constructor
@@ -1420,40 +1519,6 @@ class AzureCliCredential {
1420
1519
  }
1421
1520
  }
1422
1521
 
1423
- // Copyright (c) Microsoft Corporation.
1424
- // Licensed under the MIT license.
1425
- /**
1426
- * The default client ID for authentication
1427
- * @internal
1428
- */
1429
- // TODO: temporary - this is the Azure CLI clientID - we'll replace it when
1430
- // Developer Sign On application is available
1431
- // https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/src/Constants.cs#L9
1432
- const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
1433
- /**
1434
- * The default tenant for authentication
1435
- * @internal
1436
- */
1437
- const DefaultTenantId = "common";
1438
- (function (AzureAuthorityHosts) {
1439
- /**
1440
- * China-based Azure Authority Host
1441
- */
1442
- AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
1443
- /**
1444
- * Germany-based Azure Authority Host
1445
- */
1446
- AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
1447
- /**
1448
- * US Government Azure Authority Host
1449
- */
1450
- AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
1451
- /**
1452
- * Public Cloud Azure Authority Host
1453
- */
1454
- AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
1455
- })(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
1456
-
1457
1522
  // Copyright (c) Microsoft Corporation.
1458
1523
  let keytar;
1459
1524
  try {
@@ -2079,11 +2144,9 @@ class AuthorizationCodeCredential {
2079
2144
  }
2080
2145
  if (tokenResponse === null) {
2081
2146
  const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
2082
- const webResource = this.identityClient.createWebResource({
2147
+ const webResource = coreRestPipeline.createPipelineRequest({
2083
2148
  url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
2084
2149
  method: "POST",
2085
- disableJsonStringifyOnBody: true,
2086
- deserializationMapper: undefined,
2087
2150
  body: qs.stringify({
2088
2151
  client_id: this.clientId,
2089
2152
  grant_type: "authorization_code",
@@ -2092,13 +2155,15 @@ class AuthorizationCodeCredential {
2092
2155
  redirect_uri: this.redirectUri,
2093
2156
  client_secret: this.clientSecret
2094
2157
  }),
2095
- headers: {
2158
+ headers: coreRestPipeline.createHttpHeaders({
2096
2159
  Accept: "application/json",
2097
2160
  "Content-Type": "application/x-www-form-urlencoded"
2098
- },
2161
+ }),
2099
2162
  abortSignal: options && options.abortSignal,
2100
- spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
2101
- tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext,
2163
+ tracingOptions: {
2164
+ spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions,
2165
+ tracingContext: newOptions.tracingOptions && newOptions.tracingOptions.tracingContext
2166
+ }
2102
2167
  });
2103
2168
  tokenResponse = yield this.identityClient.sendTokenRequest(webResource);
2104
2169
  }