@azure/identity 4.0.0-alpha.20230210.3 → 4.0.0-beta.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/README.md +39 -65
- package/dist/index.js +846 -577
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +11 -2
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/constants.js +2 -0
- package/dist-esm/src/constants.js.map +1 -1
- package/dist-esm/src/credentials/authorityValidationOptions.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +6 -6
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +17 -10
- package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/azureDeveloperCliCredential.js +52 -18
- package/dist-esm/src/credentials/azureDeveloperCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureDeveloperCliCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredential.js +27 -13
- package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/brokerAuthOptions.js +2 -0
- package/dist-esm/src/credentials/brokerAuthOptions.js.map +1 -0
- package/dist-esm/src/credentials/browserCustomizationOptions.js +4 -0
- package/dist-esm/src/credentials/browserCustomizationOptions.js.map +1 -0
- package/dist-esm/src/credentials/chainedTokenCredential.js +8 -4
- package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientAssertionCredential.js +6 -6
- package/dist-esm/src/credentials/clientAssertionCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.js +6 -6
- package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.browser.js +7 -7
- package/dist-esm/src/credentials/clientSecretCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.js +8 -8
- package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js +56 -4
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +7 -7
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.browser.js +1 -1
- package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.js +3 -3
- package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +9 -9
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.js +29 -12
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +15 -4
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +65 -31
- 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 +10 -65
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredential.browser.js +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredential.js +5 -5
- package/dist-esm/src/credentials/onBehalfOfCredential.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.browser.js +6 -6
- package/dist-esm/src/credentials/usernamePasswordCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.js +7 -7
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.js +3 -4
- package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/workloadIdentityCredential.browser.js +27 -0
- package/dist-esm/src/credentials/workloadIdentityCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/workloadIdentityCredential.js +104 -0
- package/dist-esm/src/credentials/workloadIdentityCredential.js.map +1 -0
- package/dist-esm/src/credentials/workloadIdentityCredentialOptions.js +4 -0
- package/dist-esm/src/credentials/workloadIdentityCredentialOptions.js.map +1 -0
- package/dist-esm/src/errors.js.map +1 -1
- package/dist-esm/src/index.js +2 -0
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/msal/browserFlows/msalAuthCode.js +3 -1
- package/dist-esm/src/msal/browserFlows/msalAuthCode.js.map +1 -1
- package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js +2 -2
- package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js.map +1 -1
- package/dist-esm/src/msal/credentials.js.map +1 -1
- package/dist-esm/src/msal/flows.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/brokerOptions.js +2 -0
- package/dist-esm/src/msal/nodeFlows/brokerOptions.js.map +1 -0
- package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js +6 -4
- package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientAssertion.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientAssertion.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientSecret.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientSecret.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js +117 -21
- package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js +40 -139
- package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js.map +1 -1
- package/dist-esm/src/msal/types.js.map +1 -1
- package/dist-esm/src/msal/utils.browser.js +236 -0
- package/dist-esm/src/msal/utils.browser.js.map +1 -0
- package/dist-esm/src/msal/utils.js +8 -5
- package/dist-esm/src/msal/utils.js.map +1 -1
- package/dist-esm/src/plugins/consumer.js +2 -1
- package/dist-esm/src/plugins/consumer.js.map +1 -1
- package/dist-esm/src/plugins/provider.js.map +1 -1
- package/dist-esm/src/tokenCredentialOptions.js.map +1 -1
- package/dist-esm/src/util/processMultiTenantRequest.js +5 -2
- package/dist-esm/src/util/processMultiTenantRequest.js.map +1 -1
- package/dist-esm/src/util/scopeUtils.js +2 -2
- package/dist-esm/src/util/scopeUtils.js.map +1 -1
- package/dist-esm/src/util/tenantIdUtils.js +3 -3
- package/dist-esm/src/util/tenantIdUtils.js.map +1 -1
- package/package.json +24 -22
- package/types/identity.d.ts +297 -67
package/dist/index.js
CHANGED
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var msalNode = require('@azure/msal-node');
|
|
6
|
-
var logger$n = require('@azure/logger');
|
|
7
|
-
var msalCommon = require('@azure/msal-common');
|
|
3
|
+
var msalCommon = require('@azure/msal-node');
|
|
4
|
+
var logger$o = require('@azure/logger');
|
|
8
5
|
var abortController = require('@azure/abort-controller');
|
|
9
6
|
var coreUtil = require('@azure/core-util');
|
|
10
|
-
var uuid = require('uuid');
|
|
11
7
|
var coreClient = require('@azure/core-client');
|
|
12
8
|
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
|
13
9
|
var coreTracing = require('@azure/core-tracing');
|
|
14
10
|
var fs = require('fs');
|
|
15
11
|
var os = require('os');
|
|
16
12
|
var path = require('path');
|
|
17
|
-
var
|
|
13
|
+
var promises = require('fs/promises');
|
|
18
14
|
var https = require('https');
|
|
19
15
|
var child_process = require('child_process');
|
|
20
16
|
var crypto = require('crypto');
|
|
21
|
-
var
|
|
17
|
+
var util = require('util');
|
|
22
18
|
var open = require('open');
|
|
23
|
-
var stoppable = require('stoppable');
|
|
24
|
-
|
|
25
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
26
19
|
|
|
27
|
-
function
|
|
28
|
-
if (e && e.__esModule) return e;
|
|
20
|
+
function _interopNamespaceDefault(e) {
|
|
29
21
|
var n = Object.create(null);
|
|
30
22
|
if (e) {
|
|
31
23
|
Object.keys(e).forEach(function (k) {
|
|
@@ -38,21 +30,12 @@ function _interopNamespace(e) {
|
|
|
38
30
|
}
|
|
39
31
|
});
|
|
40
32
|
}
|
|
41
|
-
n
|
|
33
|
+
n.default = e;
|
|
42
34
|
return Object.freeze(n);
|
|
43
35
|
}
|
|
44
36
|
|
|
45
|
-
var
|
|
46
|
-
var
|
|
47
|
-
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
48
|
-
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
49
|
-
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
50
|
-
var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
51
|
-
var child_process__default = /*#__PURE__*/_interopDefaultLegacy(child_process);
|
|
52
|
-
var child_process__namespace = /*#__PURE__*/_interopNamespace(child_process);
|
|
53
|
-
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
54
|
-
var open__default = /*#__PURE__*/_interopDefaultLegacy(open);
|
|
55
|
-
var stoppable__default = /*#__PURE__*/_interopDefaultLegacy(stoppable);
|
|
37
|
+
var msalCommon__namespace = /*#__PURE__*/_interopNamespaceDefault(msalCommon);
|
|
38
|
+
var child_process__namespace = /*#__PURE__*/_interopNamespaceDefault(child_process);
|
|
56
39
|
|
|
57
40
|
// Copyright (c) Microsoft Corporation.
|
|
58
41
|
// Licensed under the MIT license.
|
|
@@ -174,10 +157,11 @@ class AuthenticationRequiredError extends Error {
|
|
|
174
157
|
}
|
|
175
158
|
|
|
176
159
|
// Copyright (c) Microsoft Corporation.
|
|
160
|
+
// Licensed under the MIT license.
|
|
177
161
|
/**
|
|
178
162
|
* The AzureLogger used for all clients within the identity package
|
|
179
163
|
*/
|
|
180
|
-
const logger$
|
|
164
|
+
const logger$n = logger$o.createClientLogger("identity");
|
|
181
165
|
/**
|
|
182
166
|
* 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.
|
|
183
167
|
* @param supportedEnvVars - List of environment variable names
|
|
@@ -217,7 +201,7 @@ function formatError(scope, error) {
|
|
|
217
201
|
* `[title] => [message]`
|
|
218
202
|
*
|
|
219
203
|
*/
|
|
220
|
-
function credentialLoggerInstance(title, parent, log = logger$
|
|
204
|
+
function credentialLoggerInstance(title, parent, log = logger$n) {
|
|
221
205
|
const fullTitle = parent ? `${parent.fullTitle} ${title}` : title;
|
|
222
206
|
function info(message) {
|
|
223
207
|
log.info(`${fullTitle} =>`, message);
|
|
@@ -246,7 +230,7 @@ function credentialLoggerInstance(title, parent, log = logger$m) {
|
|
|
246
230
|
* `[title] => getToken() => [message]`
|
|
247
231
|
*
|
|
248
232
|
*/
|
|
249
|
-
function credentialLogger(title, log = logger$
|
|
233
|
+
function credentialLogger(title, log = logger$n) {
|
|
250
234
|
const credLogger = credentialLoggerInstance(title, undefined, log);
|
|
251
235
|
return Object.assign(Object.assign({}, credLogger), { parent: log, getToken: credentialLoggerInstance("=> getToken()", credLogger, log) });
|
|
252
236
|
}
|
|
@@ -300,8 +284,11 @@ const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
|
|
|
300
284
|
* Allow acquiring tokens for any tenant for multi-tentant auth.
|
|
301
285
|
*/
|
|
302
286
|
const ALL_TENANTS = ["*"];
|
|
287
|
+
const CACHE_CAE_SUFFIX = ".cae";
|
|
288
|
+
const CACHE_NON_CAE_SUFFIX = ".nocae";
|
|
303
289
|
|
|
304
290
|
// Copyright (c) Microsoft Corporation.
|
|
291
|
+
// Licensed under the MIT license.
|
|
305
292
|
/**
|
|
306
293
|
* Latest AuthenticationRecord version
|
|
307
294
|
* @internal
|
|
@@ -420,7 +407,7 @@ class MsalBaseUtilities {
|
|
|
420
407
|
* Generates a UUID
|
|
421
408
|
*/
|
|
422
409
|
generateUuid() {
|
|
423
|
-
return
|
|
410
|
+
return coreUtil.randomUUID();
|
|
424
411
|
}
|
|
425
412
|
/**
|
|
426
413
|
* Handles the MSAL authentication result.
|
|
@@ -467,12 +454,16 @@ class MsalBaseUtilities {
|
|
|
467
454
|
error.name === "AbortError") {
|
|
468
455
|
return error;
|
|
469
456
|
}
|
|
457
|
+
if (error.name === "NativeAuthError") {
|
|
458
|
+
this.logger.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
|
|
459
|
+
return error;
|
|
460
|
+
}
|
|
470
461
|
return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
|
|
471
462
|
}
|
|
472
463
|
}
|
|
473
464
|
// transformations.ts
|
|
474
465
|
function publicToMsal(account) {
|
|
475
|
-
const [environment] = account.authority.match(/([a-z]*\.[a-z]*\.[a-z]*)/) || [];
|
|
466
|
+
const [environment] = account.authority.match(/([a-z]*\.[a-z]*\.[a-z]*)/) || [""];
|
|
476
467
|
return Object.assign(Object.assign({}, account), { localAccountId: account.homeAccountId, environment });
|
|
477
468
|
}
|
|
478
469
|
function msalToPublic(clientId, account) {
|
|
@@ -541,7 +532,7 @@ function createConfigurationErrorMessage(tenantId) {
|
|
|
541
532
|
* or unless the original tenant Id is `adfs`.
|
|
542
533
|
* @internal
|
|
543
534
|
*/
|
|
544
|
-
function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds = []) {
|
|
535
|
+
function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds = [], logger) {
|
|
545
536
|
var _a;
|
|
546
537
|
let resolvedTenantId;
|
|
547
538
|
if (process.env.AZURE_IDENTITY_DISABLE_MULTITENANTAUTH) {
|
|
@@ -557,18 +548,21 @@ function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowe
|
|
|
557
548
|
resolvedTenantId !== tenantId &&
|
|
558
549
|
!additionallyAllowedTenantIds.includes("*") &&
|
|
559
550
|
!additionallyAllowedTenantIds.some((t) => t.localeCompare(resolvedTenantId) === 0)) {
|
|
560
|
-
|
|
551
|
+
const message = createConfigurationErrorMessage(tenantId);
|
|
552
|
+
logger === null || logger === void 0 ? void 0 : logger.info(message);
|
|
553
|
+
throw new CredentialUnavailableError(message);
|
|
561
554
|
}
|
|
562
555
|
return resolvedTenantId;
|
|
563
556
|
}
|
|
564
557
|
|
|
565
558
|
// Copyright (c) Microsoft Corporation.
|
|
559
|
+
// Licensed under the MIT license.
|
|
566
560
|
/**
|
|
567
561
|
* @internal
|
|
568
562
|
*/
|
|
569
563
|
function checkTenantId(logger, tenantId) {
|
|
570
|
-
if (!tenantId.match(/^[0-9a-zA-Z
|
|
571
|
-
const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://
|
|
564
|
+
if (!tenantId.match(/^[0-9a-zA-Z-.]+$/)) {
|
|
565
|
+
const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://learn.microsoft.com/partner-center/find-ids-and-domain-names.");
|
|
572
566
|
logger.info(formatError("", error));
|
|
573
567
|
throw error;
|
|
574
568
|
}
|
|
@@ -592,7 +586,7 @@ function resolveTenantId(logger, tenantId, clientId) {
|
|
|
592
586
|
/**
|
|
593
587
|
* @internal
|
|
594
588
|
*/
|
|
595
|
-
function
|
|
589
|
+
function resolveAdditionallyAllowedTenantIds(additionallyAllowedTenants) {
|
|
596
590
|
if (!additionallyAllowedTenants || additionallyAllowedTenants.length === 0) {
|
|
597
591
|
return [];
|
|
598
592
|
}
|
|
@@ -614,6 +608,7 @@ function getIdentityTokenEndpointSuffix(tenantId) {
|
|
|
614
608
|
}
|
|
615
609
|
|
|
616
610
|
// Copyright (c) Microsoft Corporation.
|
|
611
|
+
// Licensed under the MIT license.
|
|
617
612
|
/**
|
|
618
613
|
* Creates a span using the global tracer.
|
|
619
614
|
* @internal
|
|
@@ -634,6 +629,7 @@ const azureArcAPIVersion = "2019-11-01";
|
|
|
634
629
|
const azureFabricVersion = "2019-07-01-preview";
|
|
635
630
|
|
|
636
631
|
// Copyright (c) Microsoft Corporation.
|
|
632
|
+
// Licensed under the MIT license.
|
|
637
633
|
/**
|
|
638
634
|
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
|
|
639
635
|
* These are GET requests that require sending a `resource` parameter on the query.
|
|
@@ -663,7 +659,7 @@ function mapScopesToResource(scopes) {
|
|
|
663
659
|
* Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
|
|
664
660
|
* @param body - A parsed response body from the authentication endpoint.
|
|
665
661
|
*/
|
|
666
|
-
function
|
|
662
|
+
function parseExpirationTimestamp(body) {
|
|
667
663
|
if (typeof body.expires_on === "number") {
|
|
668
664
|
return body.expires_on * 1000;
|
|
669
665
|
}
|
|
@@ -684,6 +680,7 @@ function parseExpiresOn(body) {
|
|
|
684
680
|
}
|
|
685
681
|
|
|
686
682
|
// Copyright (c) Microsoft Corporation.
|
|
683
|
+
// Licensed under the MIT license.
|
|
687
684
|
const noCorrelationId = "noCorrelationId";
|
|
688
685
|
/**
|
|
689
686
|
* @internal
|
|
@@ -724,9 +721,11 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
724
721
|
this.authorityHost = baseUri;
|
|
725
722
|
this.abortControllers = new Map();
|
|
726
723
|
this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
|
|
724
|
+
// used for WorkloadIdentity
|
|
725
|
+
this.tokenCredentialOptions = Object.assign({}, options);
|
|
727
726
|
}
|
|
728
727
|
async sendTokenRequest(request) {
|
|
729
|
-
logger$
|
|
728
|
+
logger$n.info(`IdentityClient: sending token request to [${request.url}]`);
|
|
730
729
|
const response = await this.sendRequest(request);
|
|
731
730
|
if (response.bodyAsText && (response.status === 200 || response.status === 201)) {
|
|
732
731
|
const parsedBody = JSON.parse(response.bodyAsText);
|
|
@@ -737,16 +736,16 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
737
736
|
const token = {
|
|
738
737
|
accessToken: {
|
|
739
738
|
token: parsedBody.access_token,
|
|
740
|
-
expiresOnTimestamp:
|
|
739
|
+
expiresOnTimestamp: parseExpirationTimestamp(parsedBody),
|
|
741
740
|
},
|
|
742
741
|
refreshToken: parsedBody.refresh_token,
|
|
743
742
|
};
|
|
744
|
-
logger$
|
|
743
|
+
logger$n.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
|
|
745
744
|
return token;
|
|
746
745
|
}
|
|
747
746
|
else {
|
|
748
747
|
const error = new AuthenticationError(response.status, response.bodyAsText);
|
|
749
|
-
logger$
|
|
748
|
+
logger$n.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
|
|
750
749
|
throw error;
|
|
751
750
|
}
|
|
752
751
|
}
|
|
@@ -754,7 +753,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
754
753
|
if (refreshToken === undefined) {
|
|
755
754
|
return null;
|
|
756
755
|
}
|
|
757
|
-
logger$
|
|
756
|
+
logger$n.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
|
|
758
757
|
const refreshParams = {
|
|
759
758
|
grant_type: "refresh_token",
|
|
760
759
|
client_id: clientId,
|
|
@@ -780,7 +779,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
780
779
|
tracingOptions: updatedOptions.tracingOptions,
|
|
781
780
|
});
|
|
782
781
|
const response = await this.sendTokenRequest(request);
|
|
783
|
-
logger$
|
|
782
|
+
logger$n.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
|
|
784
783
|
return response;
|
|
785
784
|
}
|
|
786
785
|
catch (err) {
|
|
@@ -789,11 +788,11 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
789
788
|
// It's likely that the refresh token has expired, so
|
|
790
789
|
// return null so that the credential implementation will
|
|
791
790
|
// initiate the authentication flow again.
|
|
792
|
-
logger$
|
|
791
|
+
logger$n.info(`IdentityClient: interaction required for client ID: ${clientId}`);
|
|
793
792
|
return null;
|
|
794
793
|
}
|
|
795
794
|
else {
|
|
796
|
-
logger$
|
|
795
|
+
logger$n.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`);
|
|
797
796
|
throw err;
|
|
798
797
|
}
|
|
799
798
|
}
|
|
@@ -869,6 +868,13 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
869
868
|
status: response.status,
|
|
870
869
|
};
|
|
871
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
*
|
|
873
|
+
* @internal
|
|
874
|
+
*/
|
|
875
|
+
getTokenCredentialOptions() {
|
|
876
|
+
return this.tokenCredentialOptions;
|
|
877
|
+
}
|
|
872
878
|
/**
|
|
873
879
|
* If allowLoggingAccountIdentifiers was set on the constructor options
|
|
874
880
|
* we try to log the account identifiers by parsing the received access token.
|
|
@@ -895,10 +901,10 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
895
901
|
}
|
|
896
902
|
const base64Metadata = accessToken.split(".")[1];
|
|
897
903
|
const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8"));
|
|
898
|
-
logger$
|
|
904
|
+
logger$n.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`);
|
|
899
905
|
}
|
|
900
906
|
catch (e) {
|
|
901
|
-
logger$
|
|
907
|
+
logger$n.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
|
|
902
908
|
}
|
|
903
909
|
}
|
|
904
910
|
}
|
|
@@ -1019,6 +1025,7 @@ var RegionalAuthority;
|
|
|
1019
1025
|
})(RegionalAuthority || (RegionalAuthority = {}));
|
|
1020
1026
|
|
|
1021
1027
|
// Copyright (c) Microsoft Corporation.
|
|
1028
|
+
// Licensed under the MIT license.
|
|
1022
1029
|
/**
|
|
1023
1030
|
* The current persistence provider, undefined by default.
|
|
1024
1031
|
* @internal
|
|
@@ -1033,6 +1040,25 @@ const msalNodeFlowCacheControl = {
|
|
|
1033
1040
|
persistenceProvider = pluginProvider;
|
|
1034
1041
|
},
|
|
1035
1042
|
};
|
|
1043
|
+
/**
|
|
1044
|
+
* The current native broker provider, undefined by default.
|
|
1045
|
+
* @internal
|
|
1046
|
+
*/
|
|
1047
|
+
let nativeBrokerInfo = undefined;
|
|
1048
|
+
function hasNativeBroker() {
|
|
1049
|
+
return nativeBrokerInfo !== undefined;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* An object that allows setting the native broker provider.
|
|
1053
|
+
* @internal
|
|
1054
|
+
*/
|
|
1055
|
+
const msalNodeFlowNativeBrokerControl = {
|
|
1056
|
+
setNativeBroker(broker) {
|
|
1057
|
+
nativeBrokerInfo = {
|
|
1058
|
+
broker,
|
|
1059
|
+
};
|
|
1060
|
+
},
|
|
1061
|
+
};
|
|
1036
1062
|
/**
|
|
1037
1063
|
* MSAL partial base client for Node.js.
|
|
1038
1064
|
*
|
|
@@ -1044,21 +1070,29 @@ const msalNodeFlowCacheControl = {
|
|
|
1044
1070
|
*/
|
|
1045
1071
|
class MsalNode extends MsalBaseUtilities {
|
|
1046
1072
|
constructor(options) {
|
|
1047
|
-
var _a, _b, _c, _d;
|
|
1073
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1048
1074
|
super(options);
|
|
1075
|
+
this.app = {};
|
|
1076
|
+
this.caeApp = {};
|
|
1049
1077
|
this.requiresConfidential = false;
|
|
1050
1078
|
this.msalConfig = this.defaultNodeMsalConfig(options);
|
|
1051
1079
|
this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
|
|
1052
|
-
this.additionallyAllowedTenantIds =
|
|
1080
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
|
|
1053
1081
|
this.clientId = this.msalConfig.auth.clientId;
|
|
1054
1082
|
if (options === null || options === void 0 ? void 0 : options.getAssertion) {
|
|
1055
1083
|
this.getAssertion = options.getAssertion;
|
|
1056
1084
|
}
|
|
1085
|
+
this.enableBroker = (_b = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _b === void 0 ? void 0 : _b.enabled;
|
|
1086
|
+
this.enableMsaPassthrough = (_c = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough;
|
|
1087
|
+
this.parentWindowHandle = (_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.parentWindowHandle;
|
|
1057
1088
|
// If persistence has been configured
|
|
1058
|
-
if (persistenceProvider !== undefined && ((
|
|
1059
|
-
|
|
1089
|
+
if (persistenceProvider !== undefined && ((_e = options.tokenCachePersistenceOptions) === null || _e === void 0 ? void 0 : _e.enabled)) {
|
|
1090
|
+
const nonCaeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
|
|
1091
|
+
const caeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
|
|
1092
|
+
this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
|
|
1093
|
+
this.createCachePluginCae = () => persistenceProvider(caeOptions);
|
|
1060
1094
|
}
|
|
1061
|
-
else if ((
|
|
1095
|
+
else if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
|
|
1062
1096
|
throw new Error([
|
|
1063
1097
|
"Persistent token caching was requested, but no persistence provider was configured.",
|
|
1064
1098
|
"You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
|
|
@@ -1066,7 +1100,16 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1066
1100
|
"`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
|
|
1067
1101
|
].join(" "));
|
|
1068
1102
|
}
|
|
1069
|
-
|
|
1103
|
+
// If broker has not been configured
|
|
1104
|
+
if (!hasNativeBroker() && this.enableBroker) {
|
|
1105
|
+
throw new Error([
|
|
1106
|
+
"Broker for WAM was requested to be enabled, but no native broker was configured.",
|
|
1107
|
+
"You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
|
|
1108
|
+
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
|
|
1109
|
+
"`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
|
|
1110
|
+
].join(" "));
|
|
1111
|
+
}
|
|
1112
|
+
this.azureRegion = (_g = options.regionalAuthority) !== null && _g !== void 0 ? _g : process.env.AZURE_REGIONAL_AUTHORITY_NAME;
|
|
1070
1113
|
if (this.azureRegion === RegionalAuthority.AutoDiscoverRegion) {
|
|
1071
1114
|
this.azureRegion = "AUTO_DISCOVER";
|
|
1072
1115
|
}
|
|
@@ -1075,15 +1118,13 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1075
1118
|
* Generates a MSAL configuration that generally works for Node.js
|
|
1076
1119
|
*/
|
|
1077
1120
|
defaultNodeMsalConfig(options) {
|
|
1121
|
+
var _a;
|
|
1078
1122
|
const clientId = options.clientId || DeveloperSignOnClientId;
|
|
1079
1123
|
const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
|
|
1080
1124
|
this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
|
|
1081
1125
|
const authority = getAuthority(tenantId, this.authorityHost);
|
|
1082
1126
|
this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
|
|
1083
|
-
|
|
1084
|
-
if (process.env.AZURE_IDENTITY_DISABLE_CP1) {
|
|
1085
|
-
clientCapabilities = [];
|
|
1086
|
-
}
|
|
1127
|
+
const clientCapabilities = [];
|
|
1087
1128
|
return {
|
|
1088
1129
|
auth: {
|
|
1089
1130
|
clientId,
|
|
@@ -1096,11 +1137,27 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1096
1137
|
networkClient: this.identityClient,
|
|
1097
1138
|
loggerOptions: {
|
|
1098
1139
|
loggerCallback: defaultLoggerCallback(options.logger),
|
|
1099
|
-
logLevel: getMSALLogLevel(logger$
|
|
1140
|
+
logLevel: getMSALLogLevel(logger$o.getLogLevel()),
|
|
1141
|
+
piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
|
|
1100
1142
|
},
|
|
1101
1143
|
},
|
|
1102
1144
|
};
|
|
1103
1145
|
}
|
|
1146
|
+
getApp(appType, enableCae) {
|
|
1147
|
+
const app = enableCae ? this.caeApp : this.app;
|
|
1148
|
+
if (appType === "publicFirst") {
|
|
1149
|
+
return (app.public || app.confidential);
|
|
1150
|
+
}
|
|
1151
|
+
else if (appType === "confidentialFirst") {
|
|
1152
|
+
return (app.confidential || app.public);
|
|
1153
|
+
}
|
|
1154
|
+
else if (appType === "confidential") {
|
|
1155
|
+
return app.confidential;
|
|
1156
|
+
}
|
|
1157
|
+
else {
|
|
1158
|
+
return app.public;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1104
1161
|
/**
|
|
1105
1162
|
* Prepares the MSAL applications.
|
|
1106
1163
|
*/
|
|
@@ -1112,15 +1169,38 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1112
1169
|
this.identityClient.abortRequests(options.correlationId);
|
|
1113
1170
|
});
|
|
1114
1171
|
}
|
|
1115
|
-
|
|
1172
|
+
const app = (options === null || options === void 0 ? void 0 : options.enableCae) ? this.caeApp : this.app;
|
|
1173
|
+
if (options === null || options === void 0 ? void 0 : options.enableCae) {
|
|
1174
|
+
this.msalConfig.auth.clientCapabilities = ["cp1"];
|
|
1175
|
+
}
|
|
1176
|
+
if (app.public || app.confidential) {
|
|
1116
1177
|
return;
|
|
1117
1178
|
}
|
|
1179
|
+
if ((options === null || options === void 0 ? void 0 : options.enableCae) && this.createCachePluginCae !== undefined) {
|
|
1180
|
+
this.msalConfig.cache = {
|
|
1181
|
+
cachePlugin: await this.createCachePluginCae(),
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1118
1184
|
if (this.createCachePlugin !== undefined) {
|
|
1119
1185
|
this.msalConfig.cache = {
|
|
1120
1186
|
cachePlugin: await this.createCachePlugin(),
|
|
1121
1187
|
};
|
|
1122
1188
|
}
|
|
1123
|
-
|
|
1189
|
+
if (hasNativeBroker() && this.enableBroker) {
|
|
1190
|
+
this.msalConfig.broker = {
|
|
1191
|
+
nativeBrokerPlugin: nativeBrokerInfo.broker,
|
|
1192
|
+
};
|
|
1193
|
+
if (!this.parentWindowHandle) {
|
|
1194
|
+
// error should have been thrown from within the constructor of InteractiveBrowserCredential
|
|
1195
|
+
this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
if (options === null || options === void 0 ? void 0 : options.enableCae) {
|
|
1199
|
+
this.caeApp.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
this.app.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
|
|
1203
|
+
}
|
|
1124
1204
|
if (this.getAssertion) {
|
|
1125
1205
|
this.msalConfig.auth.clientAssertion = await this.getAssertion();
|
|
1126
1206
|
}
|
|
@@ -1128,7 +1208,12 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1128
1208
|
if (this.msalConfig.auth.clientSecret ||
|
|
1129
1209
|
this.msalConfig.auth.clientAssertion ||
|
|
1130
1210
|
this.msalConfig.auth.clientCertificate) {
|
|
1131
|
-
|
|
1211
|
+
if (options === null || options === void 0 ? void 0 : options.enableCae) {
|
|
1212
|
+
this.caeApp.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
|
|
1213
|
+
}
|
|
1214
|
+
else {
|
|
1215
|
+
this.app.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
|
|
1216
|
+
}
|
|
1132
1217
|
}
|
|
1133
1218
|
else {
|
|
1134
1219
|
if (this.requiresConfidential) {
|
|
@@ -1156,12 +1241,11 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1156
1241
|
/**
|
|
1157
1242
|
* Returns the existing account, attempts to load the account from MSAL.
|
|
1158
1243
|
*/
|
|
1159
|
-
async getActiveAccount() {
|
|
1160
|
-
var _a, _b, _c;
|
|
1244
|
+
async getActiveAccount(enableCae = false) {
|
|
1161
1245
|
if (this.account) {
|
|
1162
1246
|
return this.account;
|
|
1163
1247
|
}
|
|
1164
|
-
const cache =
|
|
1248
|
+
const cache = this.getApp("confidentialFirst", enableCae).getTokenCache();
|
|
1165
1249
|
const accountsByTenant = await (cache === null || cache === void 0 ? void 0 : cache.getAllAccounts());
|
|
1166
1250
|
if (!accountsByTenant) {
|
|
1167
1251
|
return;
|
|
@@ -1184,8 +1268,8 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
1184
1268
|
* Attempts to retrieve a token from cache.
|
|
1185
1269
|
*/
|
|
1186
1270
|
async getTokenSilent(scopes, options) {
|
|
1187
|
-
var _a, _b;
|
|
1188
|
-
await this.getActiveAccount();
|
|
1271
|
+
var _a, _b, _c;
|
|
1272
|
+
await this.getActiveAccount(options === null || options === void 0 ? void 0 : options.enableCae);
|
|
1189
1273
|
if (!this.account) {
|
|
1190
1274
|
throw new AuthenticationRequiredError({
|
|
1191
1275
|
scopes,
|
|
@@ -1201,9 +1285,28 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
1201
1285
|
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
1202
1286
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
1203
1287
|
};
|
|
1288
|
+
if (hasNativeBroker() && this.enableBroker) {
|
|
1289
|
+
if (!silentRequest.tokenQueryParameters) {
|
|
1290
|
+
silentRequest.tokenQueryParameters = {};
|
|
1291
|
+
}
|
|
1292
|
+
if (!this.parentWindowHandle) {
|
|
1293
|
+
// error should have been thrown from within the constructor of InteractiveBrowserCredential
|
|
1294
|
+
this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
|
|
1295
|
+
}
|
|
1296
|
+
if (this.enableMsaPassthrough) {
|
|
1297
|
+
silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1204
1300
|
try {
|
|
1205
1301
|
this.logger.info("Attempting to acquire token silently");
|
|
1206
|
-
|
|
1302
|
+
/**
|
|
1303
|
+
* The following code to retrieve all accounts is done as a workaround in an attempt to force the
|
|
1304
|
+
* refresh of the token cache with the token and the account passed in through the
|
|
1305
|
+
* `authenticationRecord` parameter. See issue - https://github.com/Azure/azure-sdk-for-js/issues/24349#issuecomment-1496715651
|
|
1306
|
+
* This workaround serves as a workaround for silent authentication not happening when authenticationRecord is passed.
|
|
1307
|
+
*/
|
|
1308
|
+
await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
|
|
1309
|
+
const response = (_c = (await ((_b = this.getApp("confidential", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _b === void 0 ? void 0 : _b.acquireTokenSilent(silentRequest)))) !== null && _c !== void 0 ? _c : (await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenSilent(silentRequest));
|
|
1207
1310
|
return this.handleResult(scopes, this.clientId, response || undefined);
|
|
1208
1311
|
}
|
|
1209
1312
|
catch (err) {
|
|
@@ -1252,9 +1355,10 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
1252
1355
|
}
|
|
1253
1356
|
|
|
1254
1357
|
// Copyright (c) Microsoft Corporation.
|
|
1358
|
+
// Licensed under the MIT license.
|
|
1255
1359
|
const CommonTenantId = "common";
|
|
1256
1360
|
const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
|
|
1257
|
-
const logger$
|
|
1361
|
+
const logger$m = credentialLogger("VisualStudioCodeCredential");
|
|
1258
1362
|
let findCredentials = undefined;
|
|
1259
1363
|
const vsCodeCredentialControl = {
|
|
1260
1364
|
setVsCodeCredentialFinder(finder) {
|
|
@@ -1286,10 +1390,10 @@ function getPropertyFromVSCode(property) {
|
|
|
1286
1390
|
const settingsPath = ["User", "settings.json"];
|
|
1287
1391
|
// Eventually we can add more folders for more versions of VSCode.
|
|
1288
1392
|
const vsCodeFolder = "Code";
|
|
1289
|
-
const homedir =
|
|
1393
|
+
const homedir = os.homedir();
|
|
1290
1394
|
function loadProperty(...pathSegments) {
|
|
1291
|
-
const fullPath =
|
|
1292
|
-
const settings = JSON.parse(
|
|
1395
|
+
const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath);
|
|
1396
|
+
const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: "utf8" }));
|
|
1293
1397
|
return settings[property];
|
|
1294
1398
|
}
|
|
1295
1399
|
try {
|
|
@@ -1307,7 +1411,7 @@ function getPropertyFromVSCode(property) {
|
|
|
1307
1411
|
}
|
|
1308
1412
|
}
|
|
1309
1413
|
catch (e) {
|
|
1310
|
-
logger$
|
|
1414
|
+
logger$m.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
|
|
1311
1415
|
return;
|
|
1312
1416
|
}
|
|
1313
1417
|
}
|
|
@@ -1340,13 +1444,13 @@ class VisualStudioCodeCredential {
|
|
|
1340
1444
|
const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
|
|
1341
1445
|
this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
|
|
1342
1446
|
if (options && options.tenantId) {
|
|
1343
|
-
checkTenantId(logger$
|
|
1447
|
+
checkTenantId(logger$m, options.tenantId);
|
|
1344
1448
|
this.tenantId = options.tenantId;
|
|
1345
1449
|
}
|
|
1346
1450
|
else {
|
|
1347
1451
|
this.tenantId = CommonTenantId;
|
|
1348
1452
|
}
|
|
1349
|
-
this.additionallyAllowedTenantIds =
|
|
1453
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
1350
1454
|
checkUnsupportedTenant(this.tenantId);
|
|
1351
1455
|
}
|
|
1352
1456
|
/**
|
|
@@ -1380,8 +1484,7 @@ class VisualStudioCodeCredential {
|
|
|
1380
1484
|
async getToken(scopes, options) {
|
|
1381
1485
|
var _a, _b;
|
|
1382
1486
|
await this.prepareOnce();
|
|
1383
|
-
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
|
|
1384
|
-
this.tenantId;
|
|
1487
|
+
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$m) || this.tenantId;
|
|
1385
1488
|
if (findCredentials === undefined) {
|
|
1386
1489
|
throw new CredentialUnavailableError([
|
|
1387
1490
|
"No implementation of `VisualStudioCodeCredential` is available.",
|
|
@@ -1395,7 +1498,7 @@ class VisualStudioCodeCredential {
|
|
|
1395
1498
|
// Check to make sure the scope we get back is a valid scope
|
|
1396
1499
|
if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
1397
1500
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
1398
|
-
logger$
|
|
1501
|
+
logger$m.getToken.info(formatError(scopes, error));
|
|
1399
1502
|
throw error;
|
|
1400
1503
|
}
|
|
1401
1504
|
if (scopeString.indexOf("offline_access") < 0) {
|
|
@@ -1415,24 +1518,25 @@ class VisualStudioCodeCredential {
|
|
|
1415
1518
|
if (refreshToken) {
|
|
1416
1519
|
const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
|
|
1417
1520
|
if (tokenResponse) {
|
|
1418
|
-
logger$
|
|
1521
|
+
logger$m.getToken.info(formatSuccess(scopes));
|
|
1419
1522
|
return tokenResponse.accessToken;
|
|
1420
1523
|
}
|
|
1421
1524
|
else {
|
|
1422
1525
|
const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
|
|
1423
|
-
logger$
|
|
1526
|
+
logger$m.getToken.info(formatError(scopes, error));
|
|
1424
1527
|
throw error;
|
|
1425
1528
|
}
|
|
1426
1529
|
}
|
|
1427
1530
|
else {
|
|
1428
1531
|
const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
|
|
1429
|
-
logger$
|
|
1532
|
+
logger$m.getToken.info(formatError(scopes, error));
|
|
1430
1533
|
throw error;
|
|
1431
1534
|
}
|
|
1432
1535
|
}
|
|
1433
1536
|
}
|
|
1434
1537
|
|
|
1435
1538
|
// Copyright (c) Microsoft Corporation.
|
|
1539
|
+
// Licensed under the MIT license.
|
|
1436
1540
|
/**
|
|
1437
1541
|
* The context passed to an Identity plugin. This contains objects that
|
|
1438
1542
|
* plugins can use to set backend implementations.
|
|
@@ -1440,6 +1544,7 @@ class VisualStudioCodeCredential {
|
|
|
1440
1544
|
*/
|
|
1441
1545
|
const pluginContext = {
|
|
1442
1546
|
cachePluginControl: msalNodeFlowCacheControl,
|
|
1547
|
+
nativeBrokerPluginControl: msalNodeFlowNativeBrokerControl,
|
|
1443
1548
|
vsCodeCredentialControl: vsCodeCredentialControl,
|
|
1444
1549
|
};
|
|
1445
1550
|
/**
|
|
@@ -1474,12 +1579,13 @@ function useIdentityPlugin(plugin) {
|
|
|
1474
1579
|
}
|
|
1475
1580
|
|
|
1476
1581
|
// Copyright (c) Microsoft Corporation.
|
|
1582
|
+
// Licensed under the MIT license.
|
|
1477
1583
|
const msiName$6 = "ManagedIdentityCredential - AppServiceMSI 2017";
|
|
1478
|
-
const logger$
|
|
1584
|
+
const logger$l = credentialLogger(msiName$6);
|
|
1479
1585
|
/**
|
|
1480
1586
|
* Generates the options used on the request for an access token.
|
|
1481
1587
|
*/
|
|
1482
|
-
function prepareRequestOptions$
|
|
1588
|
+
function prepareRequestOptions$5(scopes, clientId) {
|
|
1483
1589
|
const resource = mapScopesToResource(scopes);
|
|
1484
1590
|
if (!resource) {
|
|
1485
1591
|
throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
|
|
@@ -1512,26 +1618,27 @@ function prepareRequestOptions$6(scopes, clientId) {
|
|
|
1512
1618
|
* 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.
|
|
1513
1619
|
*/
|
|
1514
1620
|
const appServiceMsi2017 = {
|
|
1621
|
+
name: "appServiceMsi2017",
|
|
1515
1622
|
async isAvailable({ scopes }) {
|
|
1516
1623
|
const resource = mapScopesToResource(scopes);
|
|
1517
1624
|
if (!resource) {
|
|
1518
|
-
logger$
|
|
1625
|
+
logger$l.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
|
|
1519
1626
|
return false;
|
|
1520
1627
|
}
|
|
1521
1628
|
const env = process.env;
|
|
1522
1629
|
const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
|
|
1523
1630
|
if (!result) {
|
|
1524
|
-
logger$
|
|
1631
|
+
logger$l.info(`${msiName$6}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
|
|
1525
1632
|
}
|
|
1526
1633
|
return result;
|
|
1527
1634
|
},
|
|
1528
1635
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1529
1636
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1530
1637
|
if (resourceId) {
|
|
1531
|
-
logger$
|
|
1638
|
+
logger$l.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
1532
1639
|
}
|
|
1533
|
-
logger$
|
|
1534
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1640
|
+
logger$l.info(`${msiName$6}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
1641
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
|
|
1535
1642
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1536
1643
|
allowInsecureConnection: true }));
|
|
1537
1644
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -1540,12 +1647,13 @@ const appServiceMsi2017 = {
|
|
|
1540
1647
|
};
|
|
1541
1648
|
|
|
1542
1649
|
// Copyright (c) Microsoft Corporation.
|
|
1650
|
+
// Licensed under the MIT license.
|
|
1543
1651
|
const msiName$5 = "ManagedIdentityCredential - CloudShellMSI";
|
|
1544
|
-
const logger$
|
|
1652
|
+
const logger$k = credentialLogger(msiName$5);
|
|
1545
1653
|
/**
|
|
1546
1654
|
* Generates the options used on the request for an access token.
|
|
1547
1655
|
*/
|
|
1548
|
-
function prepareRequestOptions$
|
|
1656
|
+
function prepareRequestOptions$4(scopes, clientId, resourceId) {
|
|
1549
1657
|
const resource = mapScopesToResource(scopes);
|
|
1550
1658
|
if (!resource) {
|
|
1551
1659
|
throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
|
|
@@ -1580,28 +1688,29 @@ function prepareRequestOptions$5(scopes, clientId, resourceId) {
|
|
|
1580
1688
|
* 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.
|
|
1581
1689
|
*/
|
|
1582
1690
|
const cloudShellMsi = {
|
|
1691
|
+
name: "cloudShellMsi",
|
|
1583
1692
|
async isAvailable({ scopes }) {
|
|
1584
1693
|
const resource = mapScopesToResource(scopes);
|
|
1585
1694
|
if (!resource) {
|
|
1586
|
-
logger$
|
|
1695
|
+
logger$k.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
|
|
1587
1696
|
return false;
|
|
1588
1697
|
}
|
|
1589
1698
|
const result = Boolean(process.env.MSI_ENDPOINT);
|
|
1590
1699
|
if (!result) {
|
|
1591
|
-
logger$
|
|
1700
|
+
logger$k.info(`${msiName$5}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
|
|
1592
1701
|
}
|
|
1593
1702
|
return result;
|
|
1594
1703
|
},
|
|
1595
1704
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1596
1705
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1597
1706
|
if (clientId) {
|
|
1598
|
-
logger$
|
|
1707
|
+
logger$k.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
1599
1708
|
}
|
|
1600
1709
|
if (resourceId) {
|
|
1601
|
-
logger$
|
|
1710
|
+
logger$k.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
|
1602
1711
|
}
|
|
1603
|
-
logger$
|
|
1604
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1712
|
+
logger$k.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
1713
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
|
|
1605
1714
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1606
1715
|
allowInsecureConnection: true }));
|
|
1607
1716
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -1610,12 +1719,13 @@ const cloudShellMsi = {
|
|
|
1610
1719
|
};
|
|
1611
1720
|
|
|
1612
1721
|
// Copyright (c) Microsoft Corporation.
|
|
1722
|
+
// Licensed under the MIT license.
|
|
1613
1723
|
const msiName$4 = "ManagedIdentityCredential - IMDS";
|
|
1614
|
-
const logger$
|
|
1724
|
+
const logger$j = credentialLogger(msiName$4);
|
|
1615
1725
|
/**
|
|
1616
1726
|
* Generates the options used on the request for an access token.
|
|
1617
1727
|
*/
|
|
1618
|
-
function prepareRequestOptions$
|
|
1728
|
+
function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
|
|
1619
1729
|
var _a;
|
|
1620
1730
|
const resource = mapScopesToResource(scopes);
|
|
1621
1731
|
if (!resource) {
|
|
@@ -1665,10 +1775,11 @@ const imdsMsiRetryConfig = {
|
|
|
1665
1775
|
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
1666
1776
|
*/
|
|
1667
1777
|
const imdsMsi = {
|
|
1778
|
+
name: "imdsMsi",
|
|
1668
1779
|
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
|
|
1669
1780
|
const resource = mapScopesToResource(scopes);
|
|
1670
1781
|
if (!resource) {
|
|
1671
|
-
logger$
|
|
1782
|
+
logger$j.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
|
|
1672
1783
|
return false;
|
|
1673
1784
|
}
|
|
1674
1785
|
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
|
|
@@ -1678,52 +1789,62 @@ const imdsMsi = {
|
|
|
1678
1789
|
if (!identityClient) {
|
|
1679
1790
|
throw new Error("Missing IdentityClient");
|
|
1680
1791
|
}
|
|
1681
|
-
const requestOptions = prepareRequestOptions$
|
|
1792
|
+
const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
|
|
1682
1793
|
skipMetadataHeader: true,
|
|
1683
1794
|
skipQuery: true,
|
|
1684
1795
|
});
|
|
1685
1796
|
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
|
|
1686
|
-
var _a;
|
|
1797
|
+
var _a, _b;
|
|
1687
1798
|
requestOptions.tracingOptions = options.tracingOptions;
|
|
1688
1799
|
// Create a request with a timeout since we expect that
|
|
1689
1800
|
// not having a "Metadata" header should cause an error to be
|
|
1690
1801
|
// returned quickly from the endpoint, proving its availability.
|
|
1691
1802
|
const request = coreRestPipeline.createPipelineRequest(requestOptions);
|
|
1692
|
-
// Default to
|
|
1803
|
+
// Default to 1000 if the default of 0 is used.
|
|
1693
1804
|
// Negative values can still be used to disable the timeout.
|
|
1694
|
-
request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) ||
|
|
1805
|
+
request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
|
|
1695
1806
|
// This MSI uses the imdsEndpoint to get the token, which only uses http://
|
|
1696
1807
|
request.allowInsecureConnection = true;
|
|
1808
|
+
let response;
|
|
1697
1809
|
try {
|
|
1698
|
-
logger$
|
|
1699
|
-
await identityClient.sendRequest(request);
|
|
1810
|
+
logger$j.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
|
|
1811
|
+
response = await identityClient.sendRequest(request);
|
|
1700
1812
|
}
|
|
1701
1813
|
catch (err) {
|
|
1702
1814
|
// If the request failed, or Node.js was unable to establish a connection,
|
|
1703
1815
|
// or the host was down, we'll assume the IMDS endpoint isn't available.
|
|
1704
1816
|
if (coreUtil.isError(err)) {
|
|
1705
|
-
logger$
|
|
1817
|
+
logger$j.verbose(`${msiName$4}: Caught error ${err.name}: ${err.message}`);
|
|
1706
1818
|
}
|
|
1707
|
-
|
|
1819
|
+
// This is a special case for Docker Desktop which responds with a 403 with a message that contains "A socket operation was attempted to an unreachable network"
|
|
1820
|
+
// rather than just timing out, as expected.
|
|
1821
|
+
logger$j.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
|
|
1708
1822
|
return false;
|
|
1709
1823
|
}
|
|
1824
|
+
if (response.status === 403) {
|
|
1825
|
+
if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("A socket operation was attempted to an unreachable network")) {
|
|
1826
|
+
logger$j.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
|
|
1827
|
+
logger$j.info(`${msiName$4}: ${response.bodyAsText}`);
|
|
1828
|
+
return false;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1710
1831
|
// If we received any response, the endpoint is available
|
|
1711
|
-
logger$
|
|
1832
|
+
logger$j.info(`${msiName$4}: The Azure IMDS endpoint is available`);
|
|
1712
1833
|
return true;
|
|
1713
1834
|
});
|
|
1714
1835
|
},
|
|
1715
1836
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1716
1837
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1717
1838
|
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
1718
|
-
logger$
|
|
1839
|
+
logger$j.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
|
|
1719
1840
|
}
|
|
1720
1841
|
else {
|
|
1721
|
-
logger$
|
|
1842
|
+
logger$j.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
|
|
1722
1843
|
}
|
|
1723
1844
|
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
|
|
1724
1845
|
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
|
|
1725
1846
|
try {
|
|
1726
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1847
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
|
|
1727
1848
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1728
1849
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1729
1850
|
}
|
|
@@ -1741,12 +1862,13 @@ const imdsMsi = {
|
|
|
1741
1862
|
};
|
|
1742
1863
|
|
|
1743
1864
|
// Copyright (c) Microsoft Corporation.
|
|
1865
|
+
// Licensed under the MIT license.
|
|
1744
1866
|
const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
|
|
1745
|
-
const logger$
|
|
1867
|
+
const logger$i = credentialLogger(msiName$3);
|
|
1746
1868
|
/**
|
|
1747
1869
|
* Generates the options used on the request for an access token.
|
|
1748
1870
|
*/
|
|
1749
|
-
function prepareRequestOptions$
|
|
1871
|
+
function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
1750
1872
|
const resource = mapScopesToResource(scopes);
|
|
1751
1873
|
if (!resource) {
|
|
1752
1874
|
throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
|
|
@@ -1780,7 +1902,7 @@ function prepareRequestOptions$3(scopes, clientId, resourceId) {
|
|
|
1780
1902
|
* Retrieves the file contents at the given path using promises.
|
|
1781
1903
|
* Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
|
|
1782
1904
|
*/
|
|
1783
|
-
function readFileAsync$
|
|
1905
|
+
function readFileAsync$1(path, options) {
|
|
1784
1906
|
return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
|
|
1785
1907
|
if (err) {
|
|
1786
1908
|
reject(err);
|
|
@@ -1812,15 +1934,16 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
1812
1934
|
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
|
|
1813
1935
|
*/
|
|
1814
1936
|
const arcMsi = {
|
|
1937
|
+
name: "arc",
|
|
1815
1938
|
async isAvailable({ scopes }) {
|
|
1816
1939
|
const resource = mapScopesToResource(scopes);
|
|
1817
1940
|
if (!resource) {
|
|
1818
|
-
logger$
|
|
1941
|
+
logger$i.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
|
|
1819
1942
|
return false;
|
|
1820
1943
|
}
|
|
1821
1944
|
const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
|
|
1822
1945
|
if (!result) {
|
|
1823
|
-
logger$
|
|
1946
|
+
logger$i.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
|
|
1824
1947
|
}
|
|
1825
1948
|
return result;
|
|
1826
1949
|
},
|
|
@@ -1828,18 +1951,18 @@ const arcMsi = {
|
|
|
1828
1951
|
var _a;
|
|
1829
1952
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1830
1953
|
if (clientId) {
|
|
1831
|
-
logger$
|
|
1954
|
+
logger$i.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
1832
1955
|
}
|
|
1833
1956
|
if (resourceId) {
|
|
1834
|
-
logger$
|
|
1957
|
+
logger$i.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
|
|
1835
1958
|
}
|
|
1836
|
-
logger$
|
|
1837
|
-
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1959
|
+
logger$i.info(`${msiName$3}: Authenticating.`);
|
|
1960
|
+
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
|
1838
1961
|
const filePath = await filePathRequest(identityClient, requestOptions);
|
|
1839
1962
|
if (!filePath) {
|
|
1840
1963
|
throw new Error(`${msiName$3}: Failed to find the token file.`);
|
|
1841
1964
|
}
|
|
1842
|
-
const key = await readFileAsync$
|
|
1965
|
+
const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
|
|
1843
1966
|
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
|
1844
1967
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
|
|
1845
1968
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
@@ -1850,87 +1973,220 @@ const arcMsi = {
|
|
|
1850
1973
|
};
|
|
1851
1974
|
|
|
1852
1975
|
// Copyright (c) Microsoft Corporation.
|
|
1853
|
-
|
|
1854
|
-
const logger$g = credentialLogger(msiName$2);
|
|
1855
|
-
const readFileAsync$1 = util.promisify(fs__default["default"].readFile);
|
|
1976
|
+
// Licensed under the MIT license.
|
|
1856
1977
|
/**
|
|
1857
|
-
*
|
|
1978
|
+
* MSAL client assertion client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
|
|
1979
|
+
* @internal
|
|
1858
1980
|
*/
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1981
|
+
class MsalClientAssertion extends MsalNode {
|
|
1982
|
+
constructor(options) {
|
|
1983
|
+
super(options);
|
|
1984
|
+
this.requiresConfidential = true;
|
|
1985
|
+
this.getAssertion = options.getAssertion;
|
|
1986
|
+
}
|
|
1987
|
+
async doGetToken(scopes, options = {}) {
|
|
1988
|
+
try {
|
|
1989
|
+
const assertion = await this.getAssertion();
|
|
1990
|
+
const result = await this.getApp("confidential", options.enableCae).acquireTokenByClientCredential({
|
|
1991
|
+
scopes,
|
|
1992
|
+
correlationId: options.correlationId,
|
|
1993
|
+
azureRegion: this.azureRegion,
|
|
1994
|
+
authority: options.authority,
|
|
1995
|
+
claims: options.claims,
|
|
1996
|
+
clientAssertion: assertion,
|
|
1997
|
+
});
|
|
1998
|
+
// The Client Credential flow does not return an account,
|
|
1999
|
+
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
2000
|
+
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
2001
|
+
}
|
|
2002
|
+
catch (err) {
|
|
2003
|
+
let err2 = err;
|
|
2004
|
+
if (err === null || err === undefined) {
|
|
2005
|
+
err2 = new Error(JSON.stringify(err));
|
|
2006
|
+
}
|
|
2007
|
+
else {
|
|
2008
|
+
err2 = coreUtil.isError(err) ? err : new Error(String(err));
|
|
2009
|
+
}
|
|
2010
|
+
throw this.handleError(scopes, err2, options);
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
1878
2013
|
}
|
|
2014
|
+
|
|
2015
|
+
// Copyright (c) Microsoft Corporation.
|
|
2016
|
+
// Licensed under the MIT license.
|
|
2017
|
+
const logger$h = credentialLogger("ClientAssertionCredential");
|
|
1879
2018
|
/**
|
|
1880
|
-
*
|
|
2019
|
+
* Authenticates a service principal with a JWT assertion.
|
|
1881
2020
|
*/
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
2021
|
+
class ClientAssertionCredential {
|
|
2022
|
+
/**
|
|
2023
|
+
* Creates an instance of the ClientAssertionCredential with the details
|
|
2024
|
+
* needed to authenticate against Microsoft Entra ID with a client
|
|
2025
|
+
* assertion provided by the developer through the `getAssertion` function parameter.
|
|
2026
|
+
*
|
|
2027
|
+
* @param tenantId - The Microsoft Entra tenant (directory) ID.
|
|
2028
|
+
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
2029
|
+
* @param getAssertion - A function that retrieves the assertion for the credential to use.
|
|
2030
|
+
* @param options - Options for configuring the client which makes the authentication request.
|
|
2031
|
+
*/
|
|
2032
|
+
constructor(tenantId, clientId, getAssertion, options = {}) {
|
|
2033
|
+
if (!tenantId || !clientId || !getAssertion) {
|
|
2034
|
+
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
|
|
2035
|
+
}
|
|
2036
|
+
this.tenantId = tenantId;
|
|
2037
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
2038
|
+
this.clientId = clientId;
|
|
2039
|
+
this.options = options;
|
|
2040
|
+
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$h, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2044
|
+
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
2045
|
+
*
|
|
2046
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
2047
|
+
* @param options - The options used to configure any requests this
|
|
2048
|
+
* TokenCredential implementation might make.
|
|
2049
|
+
*/
|
|
2050
|
+
async getToken(scopes, options = {}) {
|
|
2051
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
2052
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$h);
|
|
2053
|
+
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
2054
|
+
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
// Copyright (c) Microsoft Corporation.
|
|
2060
|
+
// Licensed under the MIT license.
|
|
2061
|
+
const credentialName$3 = "WorkloadIdentityCredential";
|
|
2062
|
+
/**
|
|
2063
|
+
* Contains the list of all supported environment variable names so that an
|
|
2064
|
+
* appropriate error message can be generated when no credentials can be
|
|
2065
|
+
* configured.
|
|
2066
|
+
*
|
|
2067
|
+
* @internal
|
|
2068
|
+
*/
|
|
2069
|
+
const SupportedWorkloadEnvironmentVariables = [
|
|
2070
|
+
"AZURE_TENANT_ID",
|
|
2071
|
+
"AZURE_CLIENT_ID",
|
|
2072
|
+
"AZURE_FEDERATED_TOKEN_FILE",
|
|
2073
|
+
];
|
|
2074
|
+
const logger$g = credentialLogger(credentialName$3);
|
|
2075
|
+
/**
|
|
2076
|
+
* Workload Identity authentication is a feature in Azure that allows applications running on virtual machines (VMs)
|
|
2077
|
+
* to access other Azure resources without the need for a service principal or managed identity. With Workload Identity
|
|
2078
|
+
* authentication, applications authenticate themselves using their own identity, rather than using a shared service
|
|
2079
|
+
* principal or managed identity. Under the hood, Workload Identity authentication uses the concept of Service Account
|
|
2080
|
+
* Credentials (SACs), which are automatically created by Azure and stored securely in the VM. By using Workload
|
|
2081
|
+
* Identity authentication, you can avoid the need to manage and rotate service principals or managed identities for
|
|
2082
|
+
* each application on each VM. Additionally, because SACs are created automatically and managed by Azure, you don't
|
|
2083
|
+
* need to worry about storing and securing sensitive credentials themselves.
|
|
2084
|
+
* The WorkloadIdentityCredential supports Microsoft Entra Workload ID authentication on Azure Kubernetes and acquires
|
|
2085
|
+
* a token using the SACs available in the Azure Kubernetes environment.
|
|
2086
|
+
* Refer to <a href="https://learn.microsoft.com/azure/aks/workload-identity-overview">Microsoft Entra
|
|
2087
|
+
* Workload ID</a> for more information.
|
|
2088
|
+
*/
|
|
2089
|
+
class WorkloadIdentityCredential {
|
|
2090
|
+
/**
|
|
2091
|
+
* WorkloadIdentityCredential supports Microsoft Entra Workload ID on Kubernetes.
|
|
2092
|
+
*
|
|
2093
|
+
* @param options - The identity client options to use for authentication.
|
|
2094
|
+
*/
|
|
2095
|
+
constructor(options) {
|
|
2096
|
+
this.azureFederatedTokenFileContent = undefined;
|
|
2097
|
+
this.cacheDate = undefined;
|
|
2098
|
+
// Logging environment variables for error details
|
|
2099
|
+
const assignedEnv = processEnvVars(SupportedWorkloadEnvironmentVariables).assigned.join(", ");
|
|
2100
|
+
logger$g.info(`Found the following environment variables: ${assignedEnv}`);
|
|
2101
|
+
const workloadIdentityCredentialOptions = options !== null && options !== void 0 ? options : {};
|
|
2102
|
+
const tenantId = workloadIdentityCredentialOptions.tenantId || process.env.AZURE_TENANT_ID;
|
|
2103
|
+
const clientId = workloadIdentityCredentialOptions.clientId || process.env.AZURE_CLIENT_ID;
|
|
2104
|
+
this.federatedTokenFilePath =
|
|
2105
|
+
workloadIdentityCredentialOptions.tokenFilePath || process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
2106
|
+
if (tenantId) {
|
|
2107
|
+
checkTenantId(logger$g, tenantId);
|
|
2108
|
+
}
|
|
2109
|
+
if (clientId && tenantId && this.federatedTokenFilePath) {
|
|
2110
|
+
logger$g.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
|
|
2111
|
+
this.client = new ClientAssertionCredential(tenantId, clientId, this.readFileContents.bind(this), options);
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
/**
|
|
2115
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2116
|
+
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
2117
|
+
*
|
|
2118
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
2119
|
+
* @param options - The options used to configure any requests this
|
|
2120
|
+
* TokenCredential implementation might make.
|
|
2121
|
+
*/
|
|
2122
|
+
async getToken(scopes, options) {
|
|
2123
|
+
if (!this.client) {
|
|
2124
|
+
const errorMessage = `${credentialName$3}: is unavailable. tenantId, clientId, and federatedTokenFilePath are required parameters.
|
|
2125
|
+
In DefaultAzureCredential and ManagedIdentityCredential, these can be provided as environment variables -
|
|
2126
|
+
"AZURE_TENANT_ID",
|
|
2127
|
+
"AZURE_CLIENT_ID",
|
|
2128
|
+
"AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot `;
|
|
2129
|
+
logger$g.info(errorMessage);
|
|
2130
|
+
throw new CredentialUnavailableError(errorMessage);
|
|
2131
|
+
}
|
|
2132
|
+
logger$g.info("Invoking getToken() of Client Assertion Credential");
|
|
2133
|
+
return this.client.getToken(scopes, options);
|
|
2134
|
+
}
|
|
2135
|
+
async readFileContents() {
|
|
1888
2136
|
// Cached assertions expire after 5 minutes
|
|
1889
|
-
if (cacheDate !== undefined && Date.now() - cacheDate >= 1000 * 60 * 5) {
|
|
1890
|
-
azureFederatedTokenFileContent = undefined;
|
|
2137
|
+
if (this.cacheDate !== undefined && Date.now() - this.cacheDate >= 1000 * 60 * 5) {
|
|
2138
|
+
this.azureFederatedTokenFileContent = undefined;
|
|
2139
|
+
}
|
|
2140
|
+
if (!this.federatedTokenFilePath) {
|
|
2141
|
+
throw new CredentialUnavailableError(`${credentialName$3}: is unavailable. Invalid file path provided ${this.federatedTokenFilePath}.`);
|
|
1891
2142
|
}
|
|
1892
|
-
if (!azureFederatedTokenFileContent) {
|
|
1893
|
-
const file = await
|
|
2143
|
+
if (!this.azureFederatedTokenFileContent) {
|
|
2144
|
+
const file = await promises.readFile(this.federatedTokenFilePath, "utf8");
|
|
1894
2145
|
const value = file.trim();
|
|
1895
2146
|
if (!value) {
|
|
1896
|
-
throw new
|
|
2147
|
+
throw new CredentialUnavailableError(`${credentialName$3}: is unavailable. No content on the file ${this.federatedTokenFilePath}.`);
|
|
1897
2148
|
}
|
|
1898
2149
|
else {
|
|
1899
|
-
azureFederatedTokenFileContent = value;
|
|
1900
|
-
cacheDate = Date.now();
|
|
2150
|
+
this.azureFederatedTokenFileContent = value;
|
|
2151
|
+
this.cacheDate = Date.now();
|
|
1901
2152
|
}
|
|
1902
2153
|
}
|
|
1903
|
-
return azureFederatedTokenFileContent;
|
|
2154
|
+
return this.azureFederatedTokenFileContent;
|
|
1904
2155
|
}
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
// Copyright (c) Microsoft Corporation.
|
|
2159
|
+
// Licensed under the MIT license.
|
|
2160
|
+
const msiName$2 = "ManagedIdentityCredential - Token Exchange";
|
|
2161
|
+
const logger$f = credentialLogger(msiName$2);
|
|
2162
|
+
/**
|
|
2163
|
+
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
|
|
2164
|
+
*/
|
|
2165
|
+
function tokenExchangeMsi() {
|
|
1905
2166
|
return {
|
|
2167
|
+
name: "tokenExchangeMsi",
|
|
1906
2168
|
async isAvailable({ clientId }) {
|
|
1907
2169
|
const env = process.env;
|
|
1908
|
-
const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
|
|
2170
|
+
const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
|
|
2171
|
+
env.AZURE_TENANT_ID &&
|
|
2172
|
+
process.env.AZURE_FEDERATED_TOKEN_FILE);
|
|
1909
2173
|
if (!result) {
|
|
1910
|
-
logger$
|
|
2174
|
+
logger$f.info(`${msiName$2}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
|
|
1911
2175
|
}
|
|
1912
2176
|
return result;
|
|
1913
2177
|
},
|
|
1914
2178
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1915
|
-
const {
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
}
|
|
1921
|
-
catch (err) {
|
|
1922
|
-
throw new Error(`${msiName$2}: Failed to read ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
|
|
1923
|
-
}
|
|
1924
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID)), {
|
|
1925
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1926
|
-
allowInsecureConnection: true }));
|
|
1927
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1928
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2179
|
+
const { scopes, clientId } = configuration;
|
|
2180
|
+
const identityClientTokenCredentialOptions = {};
|
|
2181
|
+
const workloadIdentityCredential = new WorkloadIdentityCredential(Object.assign(Object.assign({ clientId, tenantId: process.env.AZURE_TENANT_ID, tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE }, identityClientTokenCredentialOptions), { disableInstanceDiscovery: true }));
|
|
2182
|
+
const token = await workloadIdentityCredential.getToken(scopes, getTokenOptions);
|
|
2183
|
+
return token;
|
|
1929
2184
|
},
|
|
1930
2185
|
};
|
|
1931
2186
|
}
|
|
1932
2187
|
|
|
1933
2188
|
// Copyright (c) Microsoft Corporation.
|
|
2189
|
+
// Licensed under the MIT license.
|
|
1934
2190
|
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
|
|
1935
2191
|
//
|
|
1936
2192
|
// FROM node:12
|
|
@@ -1942,7 +2198,7 @@ function tokenExchangeMsi() {
|
|
|
1942
2198
|
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
1943
2199
|
//
|
|
1944
2200
|
const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
|
|
1945
|
-
const logger$
|
|
2201
|
+
const logger$e = credentialLogger(msiName$1);
|
|
1946
2202
|
/**
|
|
1947
2203
|
* Generates the options used on the request for an access token.
|
|
1948
2204
|
*/
|
|
@@ -1982,25 +2238,26 @@ function prepareRequestOptions$1(scopes, clientId, resourceId) {
|
|
|
1982
2238
|
* 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.
|
|
1983
2239
|
*/
|
|
1984
2240
|
const fabricMsi = {
|
|
2241
|
+
name: "fabricMsi",
|
|
1985
2242
|
async isAvailable({ scopes }) {
|
|
1986
2243
|
const resource = mapScopesToResource(scopes);
|
|
1987
2244
|
if (!resource) {
|
|
1988
|
-
logger$
|
|
2245
|
+
logger$e.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
|
|
1989
2246
|
return false;
|
|
1990
2247
|
}
|
|
1991
2248
|
const env = process.env;
|
|
1992
2249
|
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
|
|
1993
2250
|
if (!result) {
|
|
1994
|
-
logger$
|
|
2251
|
+
logger$e.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
|
|
1995
2252
|
}
|
|
1996
2253
|
return result;
|
|
1997
2254
|
},
|
|
1998
2255
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1999
2256
|
const { scopes, identityClient, clientId, resourceId } = configuration;
|
|
2000
2257
|
if (resourceId) {
|
|
2001
|
-
logger$
|
|
2258
|
+
logger$e.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2002
2259
|
}
|
|
2003
|
-
logger$
|
|
2260
|
+
logger$e.info([
|
|
2004
2261
|
`${msiName$1}:`,
|
|
2005
2262
|
"Using the endpoint and the secret coming from the environment variables:",
|
|
2006
2263
|
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
|
|
@@ -2008,7 +2265,7 @@ const fabricMsi = {
|
|
|
2008
2265
|
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
|
|
2009
2266
|
].join(" "));
|
|
2010
2267
|
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
|
|
2011
|
-
request.agent = new
|
|
2268
|
+
request.agent = new https.Agent({
|
|
2012
2269
|
// This is necessary because Service Fabric provides a self-signed certificate.
|
|
2013
2270
|
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
|
2014
2271
|
rejectUnauthorized: false,
|
|
@@ -2019,8 +2276,9 @@ const fabricMsi = {
|
|
|
2019
2276
|
};
|
|
2020
2277
|
|
|
2021
2278
|
// Copyright (c) Microsoft Corporation.
|
|
2279
|
+
// Licensed under the MIT license.
|
|
2022
2280
|
const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
|
|
2023
|
-
const logger$
|
|
2281
|
+
const logger$d = credentialLogger(msiName);
|
|
2024
2282
|
/**
|
|
2025
2283
|
* Generates the options used on the request for an access token.
|
|
2026
2284
|
*/
|
|
@@ -2060,22 +2318,23 @@ function prepareRequestOptions(scopes, clientId, resourceId) {
|
|
|
2060
2318
|
* 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.
|
|
2061
2319
|
*/
|
|
2062
2320
|
const appServiceMsi2019 = {
|
|
2321
|
+
name: "appServiceMsi2019",
|
|
2063
2322
|
async isAvailable({ scopes }) {
|
|
2064
2323
|
const resource = mapScopesToResource(scopes);
|
|
2065
2324
|
if (!resource) {
|
|
2066
|
-
logger$
|
|
2325
|
+
logger$d.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
|
|
2067
2326
|
return false;
|
|
2068
2327
|
}
|
|
2069
2328
|
const env = process.env;
|
|
2070
2329
|
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
|
|
2071
2330
|
if (!result) {
|
|
2072
|
-
logger$
|
|
2331
|
+
logger$d.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
|
|
2073
2332
|
}
|
|
2074
2333
|
return result;
|
|
2075
2334
|
},
|
|
2076
2335
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2077
2336
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2078
|
-
logger$
|
|
2337
|
+
logger$d.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
|
2079
2338
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
|
|
2080
2339
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2081
2340
|
allowInsecureConnection: true }));
|
|
@@ -2085,14 +2344,15 @@ const appServiceMsi2019 = {
|
|
|
2085
2344
|
};
|
|
2086
2345
|
|
|
2087
2346
|
// Copyright (c) Microsoft Corporation.
|
|
2088
|
-
|
|
2347
|
+
// Licensed under the MIT license.
|
|
2348
|
+
const logger$c = credentialLogger("ManagedIdentityCredential");
|
|
2089
2349
|
/**
|
|
2090
2350
|
* Attempts authentication using a managed identity available at the deployment environment.
|
|
2091
2351
|
* This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
|
|
2092
2352
|
* Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.
|
|
2093
2353
|
*
|
|
2094
2354
|
* More information about configuring managed identities can be found here:
|
|
2095
|
-
* https://
|
|
2355
|
+
* https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
|
|
2096
2356
|
*/
|
|
2097
2357
|
class ManagedIdentityCredential {
|
|
2098
2358
|
/**
|
|
@@ -2102,6 +2362,7 @@ class ManagedIdentityCredential {
|
|
|
2102
2362
|
constructor(clientIdOrOptions, options) {
|
|
2103
2363
|
var _a;
|
|
2104
2364
|
this.isEndpointUnavailable = null;
|
|
2365
|
+
this.isAppTokenProviderInitialized = false;
|
|
2105
2366
|
let _options;
|
|
2106
2367
|
if (typeof clientIdOrOptions === "string") {
|
|
2107
2368
|
this.clientId = clientIdOrOptions;
|
|
@@ -2123,12 +2384,19 @@ class ManagedIdentityCredential {
|
|
|
2123
2384
|
/** authority host validation and metadata discovery to be skipped in managed identity
|
|
2124
2385
|
* since this wasn't done previously before adding token cache support
|
|
2125
2386
|
*/
|
|
2126
|
-
this.confidentialApp = new
|
|
2387
|
+
this.confidentialApp = new msalCommon.ConfidentialClientApplication({
|
|
2127
2388
|
auth: {
|
|
2389
|
+
authority: "https://login.microsoftonline.com/managed_identity",
|
|
2128
2390
|
clientId: (_a = this.clientId) !== null && _a !== void 0 ? _a : DeveloperSignOnClientId,
|
|
2129
2391
|
clientSecret: "dummy-secret",
|
|
2130
2392
|
cloudDiscoveryMetadata: '{"tenant_discovery_endpoint":"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}',
|
|
2131
2393
|
authorityMetadata: '{"token_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/common/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"kerberos_endpoint":"https://login.microsoftonline.com/common/kerberos","tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}',
|
|
2394
|
+
clientCapabilities: [],
|
|
2395
|
+
},
|
|
2396
|
+
system: {
|
|
2397
|
+
loggerOptions: {
|
|
2398
|
+
logLevel: getMSALLogLevel(logger$o.getLogLevel()),
|
|
2399
|
+
},
|
|
2132
2400
|
},
|
|
2133
2401
|
});
|
|
2134
2402
|
}
|
|
@@ -2183,7 +2451,7 @@ class ManagedIdentityCredential {
|
|
|
2183
2451
|
}
|
|
2184
2452
|
}
|
|
2185
2453
|
/**
|
|
2186
|
-
* Authenticates with
|
|
2454
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2187
2455
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
2188
2456
|
* If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.
|
|
2189
2457
|
*
|
|
@@ -2199,35 +2467,22 @@ class ManagedIdentityCredential {
|
|
|
2199
2467
|
// If it's null, it means we don't yet know whether
|
|
2200
2468
|
// the endpoint is available and need to check for it.
|
|
2201
2469
|
if (this.isEndpointUnavailable !== true) {
|
|
2202
|
-
const
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
expiresInSeconds,
|
|
2219
|
-
};
|
|
2220
|
-
}
|
|
2221
|
-
else {
|
|
2222
|
-
logger$d.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
|
|
2223
|
-
return {
|
|
2224
|
-
accessToken: "no_access_token_returned",
|
|
2225
|
-
expiresInSeconds: 0,
|
|
2226
|
-
};
|
|
2227
|
-
}
|
|
2228
|
-
});
|
|
2229
|
-
const authenticationResult = await this.confidentialApp.acquireTokenByClientCredential(Object.assign({}, appTokenParameters));
|
|
2230
|
-
result = this.handleResult(scopes, authenticationResult || undefined);
|
|
2470
|
+
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
|
|
2471
|
+
if (availableMSI.name === "tokenExchangeMsi") {
|
|
2472
|
+
result = await this.authenticateManagedIdentity(scopes, updatedOptions);
|
|
2473
|
+
}
|
|
2474
|
+
else {
|
|
2475
|
+
const appTokenParameters = {
|
|
2476
|
+
correlationId: this.identityClient.getCorrelationId(),
|
|
2477
|
+
tenantId: (options === null || options === void 0 ? void 0 : options.tenantId) || "managed_identity",
|
|
2478
|
+
scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
2479
|
+
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
2480
|
+
};
|
|
2481
|
+
// Added a check to see if SetAppTokenProvider was already defined.
|
|
2482
|
+
this.initializeSetAppTokenProvider();
|
|
2483
|
+
const authenticationResult = await this.confidentialApp.acquireTokenByClientCredential(Object.assign({}, appTokenParameters));
|
|
2484
|
+
result = this.handleResult(scopes, authenticationResult || undefined);
|
|
2485
|
+
}
|
|
2231
2486
|
if (result === null) {
|
|
2232
2487
|
// If authenticateManagedIdentity returns null,
|
|
2233
2488
|
// it means no MSI endpoints are available.
|
|
@@ -2236,7 +2491,7 @@ class ManagedIdentityCredential {
|
|
|
2236
2491
|
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
|
|
2237
2492
|
// yet we had no access token. For this reason, we'll throw once with a specific message:
|
|
2238
2493
|
const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
|
|
2239
|
-
logger$
|
|
2494
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2240
2495
|
throw error;
|
|
2241
2496
|
}
|
|
2242
2497
|
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
|
|
@@ -2248,10 +2503,10 @@ class ManagedIdentityCredential {
|
|
|
2248
2503
|
// We've previously determined that the endpoint was unavailable,
|
|
2249
2504
|
// either because it was unreachable or permanently unable to authenticate.
|
|
2250
2505
|
const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
|
|
2251
|
-
logger$
|
|
2506
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2252
2507
|
throw error;
|
|
2253
2508
|
}
|
|
2254
|
-
logger$
|
|
2509
|
+
logger$c.getToken.info(formatSuccess(scopes));
|
|
2255
2510
|
return result;
|
|
2256
2511
|
}
|
|
2257
2512
|
catch (err) {
|
|
@@ -2273,14 +2528,14 @@ class ManagedIdentityCredential {
|
|
|
2273
2528
|
// we can safely assume the credential is unavailable.
|
|
2274
2529
|
if (err.code === "ENETUNREACH") {
|
|
2275
2530
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
|
|
2276
|
-
logger$
|
|
2531
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2277
2532
|
throw error;
|
|
2278
2533
|
}
|
|
2279
2534
|
// If either the host was unreachable,
|
|
2280
2535
|
// we can safely assume the credential is unavailable.
|
|
2281
2536
|
if (err.code === "EHOSTUNREACH") {
|
|
2282
2537
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
|
|
2283
|
-
logger$
|
|
2538
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2284
2539
|
throw error;
|
|
2285
2540
|
}
|
|
2286
2541
|
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
|
@@ -2288,6 +2543,15 @@ class ManagedIdentityCredential {
|
|
|
2288
2543
|
if (err.statusCode === 400) {
|
|
2289
2544
|
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
|
|
2290
2545
|
}
|
|
2546
|
+
// This is a special case for Docker Desktop which responds with a 403 with a message that contains "A socket operation was attempted to an unreachable network"
|
|
2547
|
+
// rather than just timing out, as expected.
|
|
2548
|
+
if (err.statusCode === 403 || err.code === 403) {
|
|
2549
|
+
if (err.message.includes("A socket operation was attempted to an unreachable network")) {
|
|
2550
|
+
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
|
|
2551
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2552
|
+
throw error;
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2291
2555
|
// If the error has no status code, we can assume there was no available identity.
|
|
2292
2556
|
// This will throw silently during any ChainedTokenCredential.
|
|
2293
2557
|
if (err.statusCode === undefined) {
|
|
@@ -2311,7 +2575,7 @@ class ManagedIdentityCredential {
|
|
|
2311
2575
|
*/
|
|
2312
2576
|
handleResult(scopes, result, getTokenOptions) {
|
|
2313
2577
|
this.ensureValidMsalToken(scopes, result, getTokenOptions);
|
|
2314
|
-
logger$
|
|
2578
|
+
logger$c.getToken.info(formatSuccess(scopes));
|
|
2315
2579
|
return {
|
|
2316
2580
|
token: result.accessToken,
|
|
2317
2581
|
expiresOnTimestamp: result.expiresOn.getTime(),
|
|
@@ -2323,7 +2587,7 @@ class ManagedIdentityCredential {
|
|
|
2323
2587
|
*/
|
|
2324
2588
|
ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
|
|
2325
2589
|
const error = (message) => {
|
|
2326
|
-
logger$
|
|
2590
|
+
logger$c.getToken.info(message);
|
|
2327
2591
|
return new AuthenticationRequiredError({
|
|
2328
2592
|
scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
2329
2593
|
getTokenOptions,
|
|
@@ -2340,9 +2604,38 @@ class ManagedIdentityCredential {
|
|
|
2340
2604
|
throw error(`Response had no "accessToken" property.`);
|
|
2341
2605
|
}
|
|
2342
2606
|
}
|
|
2607
|
+
initializeSetAppTokenProvider() {
|
|
2608
|
+
if (!this.isAppTokenProviderInitialized) {
|
|
2609
|
+
this.confidentialApp.SetAppTokenProvider(async (appTokenProviderParameters) => {
|
|
2610
|
+
logger$c.info(`SetAppTokenProvider invoked with parameters- ${JSON.stringify(appTokenProviderParameters)}`);
|
|
2611
|
+
const getTokenOptions = Object.assign({}, appTokenProviderParameters);
|
|
2612
|
+
logger$c.info(`authenticateManagedIdentity invoked with scopes- ${JSON.stringify(appTokenProviderParameters.scopes)} and getTokenOptions - ${JSON.stringify(getTokenOptions)}`);
|
|
2613
|
+
const resultToken = await this.authenticateManagedIdentity(appTokenProviderParameters.scopes, getTokenOptions);
|
|
2614
|
+
if (resultToken) {
|
|
2615
|
+
logger$c.info(`SetAppTokenProvider will save the token in cache`);
|
|
2616
|
+
const expiresInSeconds = (resultToken === null || resultToken === void 0 ? void 0 : resultToken.expiresOnTimestamp)
|
|
2617
|
+
? Math.floor((resultToken.expiresOnTimestamp - Date.now()) / 1000)
|
|
2618
|
+
: 0;
|
|
2619
|
+
return {
|
|
2620
|
+
accessToken: resultToken === null || resultToken === void 0 ? void 0 : resultToken.token,
|
|
2621
|
+
expiresInSeconds,
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
else {
|
|
2625
|
+
logger$c.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
|
|
2626
|
+
return {
|
|
2627
|
+
accessToken: "no_access_token_returned",
|
|
2628
|
+
expiresInSeconds: 0,
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
});
|
|
2632
|
+
this.isAppTokenProviderInitialized = true;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2343
2635
|
}
|
|
2344
2636
|
|
|
2345
2637
|
// Copyright (c) Microsoft Corporation.
|
|
2638
|
+
// Licensed under the MIT license.
|
|
2346
2639
|
/**
|
|
2347
2640
|
* Ensures the scopes value is an array.
|
|
2348
2641
|
* @internal
|
|
@@ -2354,8 +2647,8 @@ function ensureScopes(scopes) {
|
|
|
2354
2647
|
* Throws if the received scope is not valid.
|
|
2355
2648
|
* @internal
|
|
2356
2649
|
*/
|
|
2357
|
-
function
|
|
2358
|
-
if (!scope.match(/^[0-9a-zA-Z
|
|
2650
|
+
function ensureValidScopeForDevTimeCreds(scope, logger) {
|
|
2651
|
+
if (!scope.match(/^[0-9a-zA-Z-_.:/]+$/)) {
|
|
2359
2652
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
2360
2653
|
logger.getToken.info(formatError(scope, error));
|
|
2361
2654
|
throw error;
|
|
@@ -2370,6 +2663,7 @@ function getScopeResource(scope) {
|
|
|
2370
2663
|
}
|
|
2371
2664
|
|
|
2372
2665
|
// Copyright (c) Microsoft Corporation.
|
|
2666
|
+
// Licensed under the MIT license.
|
|
2373
2667
|
/**
|
|
2374
2668
|
* Mockable reference to the CLI credential cliCredentialFunctions
|
|
2375
2669
|
* @internal
|
|
@@ -2394,14 +2688,14 @@ const cliCredentialInternals = {
|
|
|
2394
2688
|
* @param resource - The resource to use when getting the token
|
|
2395
2689
|
* @internal
|
|
2396
2690
|
*/
|
|
2397
|
-
async getAzureCliAccessToken(resource, tenantId) {
|
|
2691
|
+
async getAzureCliAccessToken(resource, tenantId, timeout) {
|
|
2398
2692
|
let tenantSection = [];
|
|
2399
2693
|
if (tenantId) {
|
|
2400
2694
|
tenantSection = ["--tenant", tenantId];
|
|
2401
2695
|
}
|
|
2402
2696
|
return new Promise((resolve, reject) => {
|
|
2403
2697
|
try {
|
|
2404
|
-
|
|
2698
|
+
child_process.execFile("az", [
|
|
2405
2699
|
"account",
|
|
2406
2700
|
"get-access-token",
|
|
2407
2701
|
"--output",
|
|
@@ -2409,7 +2703,7 @@ const cliCredentialInternals = {
|
|
|
2409
2703
|
"--resource",
|
|
2410
2704
|
resource,
|
|
2411
2705
|
...tenantSection,
|
|
2412
|
-
], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true }, (error, stdout, stderr) => {
|
|
2706
|
+
], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true, timeout }, (error, stdout, stderr) => {
|
|
2413
2707
|
resolve({ stdout: stdout, stderr: stderr, error });
|
|
2414
2708
|
});
|
|
2415
2709
|
}
|
|
@@ -2419,7 +2713,7 @@ const cliCredentialInternals = {
|
|
|
2419
2713
|
});
|
|
2420
2714
|
},
|
|
2421
2715
|
};
|
|
2422
|
-
const logger$
|
|
2716
|
+
const logger$b = credentialLogger("AzureCliCredential");
|
|
2423
2717
|
/**
|
|
2424
2718
|
* This credential will use the currently logged-in user login information
|
|
2425
2719
|
* via the Azure CLI ('az') commandline tool.
|
|
@@ -2436,11 +2730,15 @@ class AzureCliCredential {
|
|
|
2436
2730
|
* @param options - Options, to optionally allow multi-tenant requests.
|
|
2437
2731
|
*/
|
|
2438
2732
|
constructor(options) {
|
|
2439
|
-
|
|
2440
|
-
|
|
2733
|
+
if (options === null || options === void 0 ? void 0 : options.tenantId) {
|
|
2734
|
+
checkTenantId(logger$b, options === null || options === void 0 ? void 0 : options.tenantId);
|
|
2735
|
+
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
|
|
2736
|
+
}
|
|
2737
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
2738
|
+
this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
|
|
2441
2739
|
}
|
|
2442
2740
|
/**
|
|
2443
|
-
* Authenticates with
|
|
2741
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2444
2742
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
2445
2743
|
*
|
|
2446
2744
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -2449,31 +2747,34 @@ class AzureCliCredential {
|
|
|
2449
2747
|
*/
|
|
2450
2748
|
async getToken(scopes, options = {}) {
|
|
2451
2749
|
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
|
|
2750
|
+
if (tenantId) {
|
|
2751
|
+
checkTenantId(logger$b, tenantId);
|
|
2752
|
+
}
|
|
2452
2753
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
2453
|
-
logger$
|
|
2454
|
-
ensureValidScope(scope, logger$c);
|
|
2455
|
-
const resource = getScopeResource(scope);
|
|
2754
|
+
logger$b.getToken.info(`Using the scope ${scope}`);
|
|
2456
2755
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
2457
2756
|
var _a, _b, _c, _d;
|
|
2458
2757
|
try {
|
|
2459
|
-
|
|
2758
|
+
ensureValidScopeForDevTimeCreds(scope, logger$b);
|
|
2759
|
+
const resource = getScopeResource(scope);
|
|
2760
|
+
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId, this.timeout);
|
|
2460
2761
|
const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
|
|
2461
2762
|
const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
|
|
2462
2763
|
const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
|
|
2463
2764
|
if (isNotInstallError) {
|
|
2464
2765
|
const error = new CredentialUnavailableError("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");
|
|
2465
|
-
logger$
|
|
2766
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
2466
2767
|
throw error;
|
|
2467
2768
|
}
|
|
2468
2769
|
if (isLoginError) {
|
|
2469
2770
|
const error = new CredentialUnavailableError("Please run 'az login' from a command prompt to authenticate before using this credential.");
|
|
2470
|
-
logger$
|
|
2771
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
2471
2772
|
throw error;
|
|
2472
2773
|
}
|
|
2473
2774
|
try {
|
|
2474
2775
|
const responseData = obj.stdout;
|
|
2475
2776
|
const response = JSON.parse(responseData);
|
|
2476
|
-
logger$
|
|
2777
|
+
logger$b.getToken.info(formatSuccess(scopes));
|
|
2477
2778
|
const returnValue = {
|
|
2478
2779
|
token: response.accessToken,
|
|
2479
2780
|
expiresOnTimestamp: new Date(response.expiresOn).getTime(),
|
|
@@ -2491,7 +2792,7 @@ class AzureCliCredential {
|
|
|
2491
2792
|
const error = err.name === "CredentialUnavailableError"
|
|
2492
2793
|
? err
|
|
2493
2794
|
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
|
|
2494
|
-
logger$
|
|
2795
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
2495
2796
|
throw error;
|
|
2496
2797
|
}
|
|
2497
2798
|
});
|
|
@@ -2499,6 +2800,7 @@ class AzureCliCredential {
|
|
|
2499
2800
|
}
|
|
2500
2801
|
|
|
2501
2802
|
// Copyright (c) Microsoft Corporation.
|
|
2803
|
+
// Licensed under the MIT license.
|
|
2502
2804
|
/**
|
|
2503
2805
|
* Easy to mock childProcess utils.
|
|
2504
2806
|
* @internal
|
|
@@ -2529,7 +2831,8 @@ const processUtils = {
|
|
|
2529
2831
|
};
|
|
2530
2832
|
|
|
2531
2833
|
// Copyright (c) Microsoft Corporation.
|
|
2532
|
-
|
|
2834
|
+
// Licensed under the MIT license.
|
|
2835
|
+
const logger$a = credentialLogger("AzurePowerShellCredential");
|
|
2533
2836
|
const isWindows = process.platform === "win32";
|
|
2534
2837
|
/**
|
|
2535
2838
|
* Returns a platform-appropriate command name by appending ".exe" on Windows.
|
|
@@ -2549,11 +2852,14 @@ function formatCommand(commandName) {
|
|
|
2549
2852
|
* If anything fails, an error is thrown.
|
|
2550
2853
|
* @internal
|
|
2551
2854
|
*/
|
|
2552
|
-
async function runCommands(commands) {
|
|
2855
|
+
async function runCommands(commands, timeout) {
|
|
2553
2856
|
const results = [];
|
|
2554
2857
|
for (const command of commands) {
|
|
2555
2858
|
const [file, ...parameters] = command;
|
|
2556
|
-
const result = (await processUtils.execFile(file, parameters, {
|
|
2859
|
+
const result = (await processUtils.execFile(file, parameters, {
|
|
2860
|
+
encoding: "utf8",
|
|
2861
|
+
timeout,
|
|
2862
|
+
}));
|
|
2557
2863
|
results.push(result);
|
|
2558
2864
|
}
|
|
2559
2865
|
return results;
|
|
@@ -2606,18 +2912,22 @@ class AzurePowerShellCredential {
|
|
|
2606
2912
|
* @param options - Options, to optionally allow multi-tenant requests.
|
|
2607
2913
|
*/
|
|
2608
2914
|
constructor(options) {
|
|
2609
|
-
|
|
2610
|
-
|
|
2915
|
+
if (options === null || options === void 0 ? void 0 : options.tenantId) {
|
|
2916
|
+
checkTenantId(logger$a, options === null || options === void 0 ? void 0 : options.tenantId);
|
|
2917
|
+
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
|
|
2918
|
+
}
|
|
2919
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
2920
|
+
this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
|
|
2611
2921
|
}
|
|
2612
2922
|
/**
|
|
2613
2923
|
* Gets the access token from Azure PowerShell
|
|
2614
2924
|
* @param resource - The resource to use when getting the token
|
|
2615
2925
|
*/
|
|
2616
|
-
async getAzurePowerShellAccessToken(resource, tenantId) {
|
|
2926
|
+
async getAzurePowerShellAccessToken(resource, tenantId, timeout) {
|
|
2617
2927
|
// Clone the stack to avoid mutating it while iterating
|
|
2618
2928
|
for (const powerShellCommand of [...commandStack]) {
|
|
2619
2929
|
try {
|
|
2620
|
-
await runCommands([[powerShellCommand, "/?"]]);
|
|
2930
|
+
await runCommands([[powerShellCommand, "/?"]], timeout);
|
|
2621
2931
|
}
|
|
2622
2932
|
catch (e) {
|
|
2623
2933
|
// Remove this credential from the original stack so that we don't try it again.
|
|
@@ -2631,11 +2941,15 @@ class AzurePowerShellCredential {
|
|
|
2631
2941
|
const results = await runCommands([
|
|
2632
2942
|
[
|
|
2633
2943
|
powerShellCommand,
|
|
2944
|
+
"-NoProfile",
|
|
2945
|
+
"-NonInteractive",
|
|
2634
2946
|
"-Command",
|
|
2635
2947
|
"Import-Module Az.Accounts -MinimumVersion 2.2.0 -PassThru",
|
|
2636
2948
|
],
|
|
2637
2949
|
[
|
|
2638
2950
|
powerShellCommand,
|
|
2951
|
+
"-NoProfile",
|
|
2952
|
+
"-NonInteractive",
|
|
2639
2953
|
"-Command",
|
|
2640
2954
|
`Get-AzAccessToken ${tenantSection} -ResourceUrl "${resource}" | ConvertTo-Json`,
|
|
2641
2955
|
],
|
|
@@ -2651,7 +2965,7 @@ class AzurePowerShellCredential {
|
|
|
2651
2965
|
throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`);
|
|
2652
2966
|
}
|
|
2653
2967
|
/**
|
|
2654
|
-
* Authenticates with
|
|
2968
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2655
2969
|
* If the authentication cannot be performed through PowerShell, a {@link CredentialUnavailableError} will be thrown.
|
|
2656
2970
|
*
|
|
2657
2971
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -2661,12 +2975,15 @@ class AzurePowerShellCredential {
|
|
|
2661
2975
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
2662
2976
|
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
|
|
2663
2977
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2978
|
+
if (tenantId) {
|
|
2979
|
+
checkTenantId(logger$a, tenantId);
|
|
2980
|
+
}
|
|
2667
2981
|
try {
|
|
2668
|
-
|
|
2669
|
-
logger$
|
|
2982
|
+
ensureValidScopeForDevTimeCreds(scope, logger$a);
|
|
2983
|
+
logger$a.getToken.info(`Using the scope ${scope}`);
|
|
2984
|
+
const resource = getScopeResource(scope);
|
|
2985
|
+
const response = await this.getAzurePowerShellAccessToken(resource, tenantId, this.timeout);
|
|
2986
|
+
logger$a.getToken.info(formatSuccess(scopes));
|
|
2670
2987
|
return {
|
|
2671
2988
|
token: response.Token,
|
|
2672
2989
|
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
|
|
@@ -2675,16 +2992,16 @@ class AzurePowerShellCredential {
|
|
|
2675
2992
|
catch (err) {
|
|
2676
2993
|
if (isNotInstalledError(err)) {
|
|
2677
2994
|
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
|
|
2678
|
-
logger$
|
|
2995
|
+
logger$a.getToken.info(formatError(scope, error));
|
|
2679
2996
|
throw error;
|
|
2680
2997
|
}
|
|
2681
2998
|
else if (isLoginError(err)) {
|
|
2682
2999
|
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
|
|
2683
|
-
logger$
|
|
3000
|
+
logger$a.getToken.info(formatError(scope, error));
|
|
2684
3001
|
throw error;
|
|
2685
3002
|
}
|
|
2686
3003
|
const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
|
|
2687
|
-
logger$
|
|
3004
|
+
logger$a.getToken.info(formatError(scope, error));
|
|
2688
3005
|
throw error;
|
|
2689
3006
|
}
|
|
2690
3007
|
});
|
|
@@ -2692,10 +3009,11 @@ class AzurePowerShellCredential {
|
|
|
2692
3009
|
}
|
|
2693
3010
|
|
|
2694
3011
|
// Copyright (c) Microsoft Corporation.
|
|
3012
|
+
// Licensed under the MIT license.
|
|
2695
3013
|
/**
|
|
2696
3014
|
* @internal
|
|
2697
3015
|
*/
|
|
2698
|
-
const logger$
|
|
3016
|
+
const logger$9 = credentialLogger("ChainedTokenCredential");
|
|
2699
3017
|
/**
|
|
2700
3018
|
* Enables multiple `TokenCredential` implementations to be tried in order
|
|
2701
3019
|
* until one of the getToken methods returns an access token.
|
|
@@ -2731,14 +3049,18 @@ class ChainedTokenCredential {
|
|
|
2731
3049
|
* `TokenCredential` implementation might make.
|
|
2732
3050
|
*/
|
|
2733
3051
|
async getToken(scopes, options = {}) {
|
|
3052
|
+
const { token } = await this.getTokenInternal(scopes, options);
|
|
3053
|
+
return token;
|
|
3054
|
+
}
|
|
3055
|
+
async getTokenInternal(scopes, options = {}) {
|
|
2734
3056
|
let token = null;
|
|
2735
|
-
let
|
|
3057
|
+
let successfulCredential;
|
|
2736
3058
|
const errors = [];
|
|
2737
3059
|
return tracingClient.withSpan("ChainedTokenCredential.getToken", options, async (updatedOptions) => {
|
|
2738
3060
|
for (let i = 0; i < this._sources.length && token === null; i++) {
|
|
2739
3061
|
try {
|
|
2740
3062
|
token = await this._sources[i].getToken(scopes, updatedOptions);
|
|
2741
|
-
|
|
3063
|
+
successfulCredential = this._sources[i];
|
|
2742
3064
|
}
|
|
2743
3065
|
catch (err) {
|
|
2744
3066
|
if (err.name === "CredentialUnavailableError" ||
|
|
@@ -2746,26 +3068,27 @@ class ChainedTokenCredential {
|
|
|
2746
3068
|
errors.push(err);
|
|
2747
3069
|
}
|
|
2748
3070
|
else {
|
|
2749
|
-
logger$
|
|
3071
|
+
logger$9.getToken.info(formatError(scopes, err));
|
|
2750
3072
|
throw err;
|
|
2751
3073
|
}
|
|
2752
3074
|
}
|
|
2753
3075
|
}
|
|
2754
3076
|
if (!token && errors.length > 0) {
|
|
2755
3077
|
const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed.");
|
|
2756
|
-
logger$
|
|
3078
|
+
logger$9.getToken.info(formatError(scopes, err));
|
|
2757
3079
|
throw err;
|
|
2758
3080
|
}
|
|
2759
|
-
logger$
|
|
3081
|
+
logger$9.getToken.info(`Result for ${successfulCredential.constructor.name}: ${formatSuccess(scopes)}`);
|
|
2760
3082
|
if (token === null) {
|
|
2761
3083
|
throw new CredentialUnavailableError("Failed to retrieve a valid token");
|
|
2762
3084
|
}
|
|
2763
|
-
return token;
|
|
3085
|
+
return { token, successfulCredential };
|
|
2764
3086
|
});
|
|
2765
3087
|
}
|
|
2766
3088
|
}
|
|
2767
3089
|
|
|
2768
3090
|
// Copyright (c) Microsoft Corporation.
|
|
3091
|
+
// Licensed under the MIT license.
|
|
2769
3092
|
const readFileAsync = util.promisify(fs.readFile);
|
|
2770
3093
|
/**
|
|
2771
3094
|
* Tries to asynchronously load a certificate from the given path.
|
|
@@ -2858,7 +3181,7 @@ class MsalClientCertificate extends MsalNode {
|
|
|
2858
3181
|
authority: options.authority,
|
|
2859
3182
|
claims: options.claims,
|
|
2860
3183
|
};
|
|
2861
|
-
const result = await this.
|
|
3184
|
+
const result = await this.getApp("confidential", options.enableCae).acquireTokenByClientCredential(clientCredReq);
|
|
2862
3185
|
// Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,
|
|
2863
3186
|
// The Client Credential flow does not return the account information from the authentication service,
|
|
2864
3187
|
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
@@ -2871,14 +3194,15 @@ class MsalClientCertificate extends MsalNode {
|
|
|
2871
3194
|
}
|
|
2872
3195
|
|
|
2873
3196
|
// Copyright (c) Microsoft Corporation.
|
|
3197
|
+
// Licensed under the MIT license.
|
|
2874
3198
|
const credentialName$2 = "ClientCertificateCredential";
|
|
2875
|
-
const logger$
|
|
3199
|
+
const logger$8 = credentialLogger(credentialName$2);
|
|
2876
3200
|
/**
|
|
2877
|
-
* Enables authentication to
|
|
3201
|
+
* Enables authentication to Microsoft Entra ID using a PEM-encoded
|
|
2878
3202
|
* certificate that is assigned to an App Registration. More information
|
|
2879
3203
|
* on how to configure certificate authentication can be found here:
|
|
2880
3204
|
*
|
|
2881
|
-
* https://
|
|
3205
|
+
* https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad
|
|
2882
3206
|
*
|
|
2883
3207
|
*/
|
|
2884
3208
|
class ClientCertificateCredential {
|
|
@@ -2887,7 +3211,7 @@ class ClientCertificateCredential {
|
|
|
2887
3211
|
throw new Error(`${credentialName$2}: tenantId and clientId are required parameters.`);
|
|
2888
3212
|
}
|
|
2889
3213
|
this.tenantId = tenantId;
|
|
2890
|
-
this.additionallyAllowedTenantIds =
|
|
3214
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
2891
3215
|
const configuration = Object.assign({}, (typeof certificatePathOrConfiguration === "string"
|
|
2892
3216
|
? {
|
|
2893
3217
|
certificatePath: certificatePathOrConfiguration,
|
|
@@ -2903,12 +3227,12 @@ class ClientCertificateCredential {
|
|
|
2903
3227
|
throw new Error(`${credentialName$2}: To avoid unexpected behaviors, providing both the contents of a PEM certificate and the path to a PEM certificate is forbidden. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
|
|
2904
3228
|
}
|
|
2905
3229
|
this.msalFlow = new MsalClientCertificate(Object.assign(Object.assign({}, options), { configuration,
|
|
2906
|
-
logger: logger$
|
|
3230
|
+
logger: logger$8,
|
|
2907
3231
|
clientId,
|
|
2908
3232
|
tenantId, sendCertificateChain: options.sendCertificateChain, tokenCredentialOptions: options }));
|
|
2909
3233
|
}
|
|
2910
3234
|
/**
|
|
2911
|
-
* Authenticates with
|
|
3235
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2912
3236
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
2913
3237
|
*
|
|
2914
3238
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -2917,7 +3241,7 @@ class ClientCertificateCredential {
|
|
|
2917
3241
|
*/
|
|
2918
3242
|
async getToken(scopes, options = {}) {
|
|
2919
3243
|
return tracingClient.withSpan(`${credentialName$2}.getToken`, options, async (newOptions) => {
|
|
2920
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
3244
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$8);
|
|
2921
3245
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
2922
3246
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
2923
3247
|
});
|
|
@@ -2925,6 +3249,7 @@ class ClientCertificateCredential {
|
|
|
2925
3249
|
}
|
|
2926
3250
|
|
|
2927
3251
|
// Copyright (c) Microsoft Corporation.
|
|
3252
|
+
// Licensed under the MIT license.
|
|
2928
3253
|
/**
|
|
2929
3254
|
* MSAL client secret client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
|
|
2930
3255
|
* @internal
|
|
@@ -2937,7 +3262,7 @@ class MsalClientSecret extends MsalNode {
|
|
|
2937
3262
|
}
|
|
2938
3263
|
async doGetToken(scopes, options = {}) {
|
|
2939
3264
|
try {
|
|
2940
|
-
const result = await this.
|
|
3265
|
+
const result = await this.getApp("confidential", options.enableCae).acquireTokenByClientCredential({
|
|
2941
3266
|
scopes,
|
|
2942
3267
|
correlationId: options.correlationId,
|
|
2943
3268
|
azureRegion: this.azureRegion,
|
|
@@ -2955,22 +3280,23 @@ class MsalClientSecret extends MsalNode {
|
|
|
2955
3280
|
}
|
|
2956
3281
|
|
|
2957
3282
|
// Copyright (c) Microsoft Corporation.
|
|
2958
|
-
|
|
3283
|
+
// Licensed under the MIT license.
|
|
3284
|
+
const logger$7 = credentialLogger("ClientSecretCredential");
|
|
2959
3285
|
/**
|
|
2960
|
-
* Enables authentication to
|
|
3286
|
+
* Enables authentication to Microsoft Entra ID using a client secret
|
|
2961
3287
|
* that was generated for an App Registration. More information on how
|
|
2962
3288
|
* to configure a client secret can be found here:
|
|
2963
3289
|
*
|
|
2964
|
-
* https://
|
|
3290
|
+
* https://learn.microsoft.com/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
|
|
2965
3291
|
*
|
|
2966
3292
|
*/
|
|
2967
3293
|
class ClientSecretCredential {
|
|
2968
3294
|
/**
|
|
2969
3295
|
* Creates an instance of the ClientSecretCredential with the details
|
|
2970
|
-
* needed to authenticate against
|
|
3296
|
+
* needed to authenticate against Microsoft Entra ID with a client
|
|
2971
3297
|
* secret.
|
|
2972
3298
|
*
|
|
2973
|
-
* @param tenantId - The
|
|
3299
|
+
* @param tenantId - The Microsoft Entra tenant (directory) ID.
|
|
2974
3300
|
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
2975
3301
|
* @param clientSecret - A client secret that was generated for the App Registration.
|
|
2976
3302
|
* @param options - Options for configuring the client which makes the authentication request.
|
|
@@ -2980,14 +3306,14 @@ class ClientSecretCredential {
|
|
|
2980
3306
|
throw new Error("ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.");
|
|
2981
3307
|
}
|
|
2982
3308
|
this.tenantId = tenantId;
|
|
2983
|
-
this.additionallyAllowedTenantIds =
|
|
2984
|
-
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$
|
|
3309
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3310
|
+
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$7,
|
|
2985
3311
|
clientId,
|
|
2986
3312
|
tenantId,
|
|
2987
3313
|
clientSecret, tokenCredentialOptions: options }));
|
|
2988
3314
|
}
|
|
2989
3315
|
/**
|
|
2990
|
-
* Authenticates with
|
|
3316
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
2991
3317
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
2992
3318
|
*
|
|
2993
3319
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -2996,7 +3322,7 @@ class ClientSecretCredential {
|
|
|
2996
3322
|
*/
|
|
2997
3323
|
async getToken(scopes, options = {}) {
|
|
2998
3324
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
2999
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
3325
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$7);
|
|
3000
3326
|
const arrayScopes = ensureScopes(scopes);
|
|
3001
3327
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3002
3328
|
});
|
|
@@ -3004,6 +3330,7 @@ class ClientSecretCredential {
|
|
|
3004
3330
|
}
|
|
3005
3331
|
|
|
3006
3332
|
// Copyright (c) Microsoft Corporation.
|
|
3333
|
+
// Licensed under the MIT license.
|
|
3007
3334
|
/**
|
|
3008
3335
|
* MSAL username and password client. Calls to the MSAL's public application's `acquireTokenByUsernamePassword` during `doGetToken`.
|
|
3009
3336
|
* @internal
|
|
@@ -3024,7 +3351,7 @@ class MsalUsernamePassword extends MsalNode {
|
|
|
3024
3351
|
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3025
3352
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3026
3353
|
};
|
|
3027
|
-
const result = await this.
|
|
3354
|
+
const result = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByUsernamePassword(requestOptions);
|
|
3028
3355
|
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
3029
3356
|
}
|
|
3030
3357
|
catch (error) {
|
|
@@ -3034,9 +3361,10 @@ class MsalUsernamePassword extends MsalNode {
|
|
|
3034
3361
|
}
|
|
3035
3362
|
|
|
3036
3363
|
// Copyright (c) Microsoft Corporation.
|
|
3037
|
-
|
|
3364
|
+
// Licensed under the MIT license.
|
|
3365
|
+
const logger$6 = credentialLogger("UsernamePasswordCredential");
|
|
3038
3366
|
/**
|
|
3039
|
-
* Enables authentication to
|
|
3367
|
+
* Enables authentication to Microsoft Entra ID with a user's
|
|
3040
3368
|
* username and password. This credential requires a high degree of
|
|
3041
3369
|
* trust so you should only use it when other, more secure credential
|
|
3042
3370
|
* types can't be used.
|
|
@@ -3044,10 +3372,10 @@ const logger$7 = credentialLogger("UsernamePasswordCredential");
|
|
|
3044
3372
|
class UsernamePasswordCredential {
|
|
3045
3373
|
/**
|
|
3046
3374
|
* Creates an instance of the UsernamePasswordCredential with the details
|
|
3047
|
-
* needed to authenticate against
|
|
3375
|
+
* needed to authenticate against Microsoft Entra ID with a username
|
|
3048
3376
|
* and password.
|
|
3049
3377
|
*
|
|
3050
|
-
* @param tenantId - The
|
|
3378
|
+
* @param tenantId - The Microsoft Entra tenant (directory).
|
|
3051
3379
|
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
3052
3380
|
* @param username - The user account's e-mail address (user name).
|
|
3053
3381
|
* @param password - The user account's account password
|
|
@@ -3058,15 +3386,15 @@ class UsernamePasswordCredential {
|
|
|
3058
3386
|
throw new Error("UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.");
|
|
3059
3387
|
}
|
|
3060
3388
|
this.tenantId = tenantId;
|
|
3061
|
-
this.additionallyAllowedTenantIds =
|
|
3062
|
-
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$
|
|
3389
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3390
|
+
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$6,
|
|
3063
3391
|
clientId,
|
|
3064
3392
|
tenantId,
|
|
3065
3393
|
username,
|
|
3066
3394
|
password, tokenCredentialOptions: options || {} }));
|
|
3067
3395
|
}
|
|
3068
3396
|
/**
|
|
3069
|
-
* Authenticates with
|
|
3397
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3070
3398
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3071
3399
|
*
|
|
3072
3400
|
* If the user provided the option `disableAutomaticAuthentication`,
|
|
@@ -3079,7 +3407,7 @@ class UsernamePasswordCredential {
|
|
|
3079
3407
|
*/
|
|
3080
3408
|
async getToken(scopes, options = {}) {
|
|
3081
3409
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3082
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
3410
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$6);
|
|
3083
3411
|
const arrayScopes = ensureScopes(scopes);
|
|
3084
3412
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3085
3413
|
});
|
|
@@ -3087,6 +3415,7 @@ class UsernamePasswordCredential {
|
|
|
3087
3415
|
}
|
|
3088
3416
|
|
|
3089
3417
|
// Copyright (c) Microsoft Corporation.
|
|
3418
|
+
// Licensed under the MIT license.
|
|
3090
3419
|
/**
|
|
3091
3420
|
* Contains the list of all supported environment variable names so that an
|
|
3092
3421
|
* appropriate error message can be generated when no credentials can be
|
|
@@ -3110,9 +3439,9 @@ function getAdditionallyAllowedTenants() {
|
|
|
3110
3439
|
return additionallyAllowedValues.split(";");
|
|
3111
3440
|
}
|
|
3112
3441
|
const credentialName$1 = "EnvironmentCredential";
|
|
3113
|
-
const logger$
|
|
3442
|
+
const logger$5 = credentialLogger(credentialName$1);
|
|
3114
3443
|
/**
|
|
3115
|
-
* Enables authentication to
|
|
3444
|
+
* Enables authentication to Microsoft Entra ID using a client secret or certificate, or as a user
|
|
3116
3445
|
* with a username and password.
|
|
3117
3446
|
*/
|
|
3118
3447
|
class EnvironmentCredential {
|
|
@@ -3120,7 +3449,7 @@ class EnvironmentCredential {
|
|
|
3120
3449
|
* Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables.
|
|
3121
3450
|
*
|
|
3122
3451
|
* Required environment variables:
|
|
3123
|
-
* - `AZURE_TENANT_ID`: The
|
|
3452
|
+
* - `AZURE_TENANT_ID`: The Microsoft Entra tenant (directory) ID.
|
|
3124
3453
|
* - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant.
|
|
3125
3454
|
*
|
|
3126
3455
|
* If setting the AZURE_TENANT_ID, then you can also set the additionally allowed tenants
|
|
@@ -3144,34 +3473,34 @@ class EnvironmentCredential {
|
|
|
3144
3473
|
// Keep track of any missing environment variables for error details
|
|
3145
3474
|
this._credential = undefined;
|
|
3146
3475
|
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
|
|
3147
|
-
logger$
|
|
3476
|
+
logger$5.info(`Found the following environment variables: ${assigned}`);
|
|
3148
3477
|
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
3149
3478
|
const additionallyAllowedTenantIds = getAdditionallyAllowedTenants();
|
|
3150
3479
|
const newOptions = Object.assign(Object.assign({}, options), { additionallyAllowedTenantIds });
|
|
3151
3480
|
if (tenantId) {
|
|
3152
|
-
checkTenantId(logger$
|
|
3481
|
+
checkTenantId(logger$5, tenantId);
|
|
3153
3482
|
}
|
|
3154
3483
|
if (tenantId && clientId && clientSecret) {
|
|
3155
|
-
logger$
|
|
3484
|
+
logger$5.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
|
|
3156
3485
|
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, newOptions);
|
|
3157
3486
|
return;
|
|
3158
3487
|
}
|
|
3159
3488
|
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
|
|
3160
3489
|
const certificatePassword = process.env.AZURE_CLIENT_CERTIFICATE_PASSWORD;
|
|
3161
3490
|
if (tenantId && clientId && certificatePath) {
|
|
3162
|
-
logger$
|
|
3491
|
+
logger$5.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
|
|
3163
3492
|
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath, certificatePassword }, newOptions);
|
|
3164
3493
|
return;
|
|
3165
3494
|
}
|
|
3166
3495
|
const username = process.env.AZURE_USERNAME;
|
|
3167
3496
|
const password = process.env.AZURE_PASSWORD;
|
|
3168
3497
|
if (tenantId && clientId && username && password) {
|
|
3169
|
-
logger$
|
|
3498
|
+
logger$5.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
|
|
3170
3499
|
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, newOptions);
|
|
3171
3500
|
}
|
|
3172
3501
|
}
|
|
3173
3502
|
/**
|
|
3174
|
-
* Authenticates with
|
|
3503
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3175
3504
|
*
|
|
3176
3505
|
* @param scopes - The list of scopes for which the token will have access.
|
|
3177
3506
|
* @param options - Optional parameters. See {@link GetTokenOptions}.
|
|
@@ -3181,7 +3510,7 @@ class EnvironmentCredential {
|
|
|
3181
3510
|
if (this._credential) {
|
|
3182
3511
|
try {
|
|
3183
3512
|
const result = await this._credential.getToken(scopes, newOptions);
|
|
3184
|
-
logger$
|
|
3513
|
+
logger$5.getToken.info(formatSuccess(scopes));
|
|
3185
3514
|
return result;
|
|
3186
3515
|
}
|
|
3187
3516
|
catch (err) {
|
|
@@ -3189,7 +3518,7 @@ class EnvironmentCredential {
|
|
|
3189
3518
|
error: `${credentialName$1} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
|
|
3190
3519
|
error_description: err.message.toString().split("More details:").join(""),
|
|
3191
3520
|
});
|
|
3192
|
-
logger$
|
|
3521
|
+
logger$5.getToken.info(formatError(scopes, authenticationError));
|
|
3193
3522
|
throw authenticationError;
|
|
3194
3523
|
}
|
|
3195
3524
|
}
|
|
@@ -3199,6 +3528,7 @@ class EnvironmentCredential {
|
|
|
3199
3528
|
}
|
|
3200
3529
|
|
|
3201
3530
|
// Copyright (c) Microsoft Corporation.
|
|
3531
|
+
// Licensed under the MIT license.
|
|
3202
3532
|
/**
|
|
3203
3533
|
* Mockable reference to the Developer CLI credential cliCredentialFunctions
|
|
3204
3534
|
* @internal
|
|
@@ -3223,21 +3553,24 @@ const developerCliCredentialInternals = {
|
|
|
3223
3553
|
* @param scopes - The scopes to use when getting the token
|
|
3224
3554
|
* @internal
|
|
3225
3555
|
*/
|
|
3226
|
-
async getAzdAccessToken(scopes, tenantId) {
|
|
3556
|
+
async getAzdAccessToken(scopes, tenantId, timeout) {
|
|
3227
3557
|
let tenantSection = [];
|
|
3228
3558
|
if (tenantId) {
|
|
3229
3559
|
tenantSection = ["--tenant-id", tenantId];
|
|
3230
3560
|
}
|
|
3231
3561
|
return new Promise((resolve, reject) => {
|
|
3232
3562
|
try {
|
|
3233
|
-
|
|
3563
|
+
child_process.execFile("azd", [
|
|
3234
3564
|
"auth",
|
|
3235
3565
|
"token",
|
|
3236
3566
|
"--output",
|
|
3237
3567
|
"json",
|
|
3238
3568
|
...scopes.reduce((previous, current) => previous.concat("--scope", current), []),
|
|
3239
3569
|
...tenantSection,
|
|
3240
|
-
], {
|
|
3570
|
+
], {
|
|
3571
|
+
cwd: developerCliCredentialInternals.getSafeWorkingDir(),
|
|
3572
|
+
timeout,
|
|
3573
|
+
}, (error, stdout, stderr) => {
|
|
3241
3574
|
resolve({ stdout, stderr, error });
|
|
3242
3575
|
});
|
|
3243
3576
|
}
|
|
@@ -3247,28 +3580,51 @@ const developerCliCredentialInternals = {
|
|
|
3247
3580
|
});
|
|
3248
3581
|
},
|
|
3249
3582
|
};
|
|
3250
|
-
const logger$
|
|
3583
|
+
const logger$4 = credentialLogger("AzureDeveloperCliCredential");
|
|
3251
3584
|
/**
|
|
3252
|
-
*
|
|
3253
|
-
*
|
|
3254
|
-
*
|
|
3255
|
-
*
|
|
3585
|
+
* Azure Developer CLI is a command-line interface tool that allows developers to create, manage, and deploy
|
|
3586
|
+
* resources in Azure. It's built on top of the Azure CLI and provides additional functionality specific
|
|
3587
|
+
* to Azure developers. It allows users to authenticate as a user and/or a service principal against
|
|
3588
|
+
* <a href="https://learn.microsoft.com/azure/active-directory/fundamentals/">Microsoft Entra ID</a>. The
|
|
3589
|
+
* AzureDeveloperCliCredential authenticates in a development environment and acquires a token on behalf of
|
|
3590
|
+
* the logged-in user or service principal in the Azure Developer CLI. It acts as the Azure Developer CLI logged in user or
|
|
3591
|
+
* service principal and executes an Azure CLI command underneath to authenticate the application against
|
|
3592
|
+
* Microsoft Entra ID.
|
|
3593
|
+
*
|
|
3594
|
+
* <h2> Configure AzureDeveloperCliCredential </h2>
|
|
3595
|
+
*
|
|
3596
|
+
* To use this credential, the developer needs to authenticate locally in Azure Developer CLI using one of the
|
|
3597
|
+
* commands below:
|
|
3598
|
+
*
|
|
3599
|
+
* <ol>
|
|
3600
|
+
* <li>Run "azd auth login" in Azure Developer CLI to authenticate interactively as a user.</li>
|
|
3601
|
+
* <li>Run "azd auth login --client-id clientID --client-secret clientSecret
|
|
3602
|
+
* --tenant-id tenantID" to authenticate as a service principal.</li>
|
|
3603
|
+
* </ol>
|
|
3604
|
+
*
|
|
3605
|
+
* You may need to repeat this process after a certain time period, depending on the refresh token validity in your
|
|
3606
|
+
* organization. Generally, the refresh token validity period is a few weeks to a few months.
|
|
3607
|
+
* AzureDeveloperCliCredential will prompt you to sign in again.
|
|
3256
3608
|
*/
|
|
3257
3609
|
class AzureDeveloperCliCredential {
|
|
3258
3610
|
/**
|
|
3259
3611
|
* Creates an instance of the {@link AzureDeveloperCliCredential}.
|
|
3260
3612
|
*
|
|
3261
3613
|
* To use this credential, ensure that you have already logged
|
|
3262
|
-
* in via the 'azd' tool using the command "azd login" from the commandline.
|
|
3614
|
+
* in via the 'azd' tool using the command "azd auth login" from the commandline.
|
|
3263
3615
|
*
|
|
3264
3616
|
* @param options - Options, to optionally allow multi-tenant requests.
|
|
3265
3617
|
*/
|
|
3266
3618
|
constructor(options) {
|
|
3267
|
-
|
|
3268
|
-
|
|
3619
|
+
if (options === null || options === void 0 ? void 0 : options.tenantId) {
|
|
3620
|
+
checkTenantId(logger$4, options === null || options === void 0 ? void 0 : options.tenantId);
|
|
3621
|
+
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
|
|
3622
|
+
}
|
|
3623
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3624
|
+
this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
|
|
3269
3625
|
}
|
|
3270
3626
|
/**
|
|
3271
|
-
* Authenticates with
|
|
3627
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3272
3628
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3273
3629
|
*
|
|
3274
3630
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -3277,6 +3633,9 @@ class AzureDeveloperCliCredential {
|
|
|
3277
3633
|
*/
|
|
3278
3634
|
async getToken(scopes, options = {}) {
|
|
3279
3635
|
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
|
|
3636
|
+
if (tenantId) {
|
|
3637
|
+
checkTenantId(logger$4, tenantId);
|
|
3638
|
+
}
|
|
3280
3639
|
let scopeList;
|
|
3281
3640
|
if (typeof scopes === "string") {
|
|
3282
3641
|
scopeList = [scopes];
|
|
@@ -3284,27 +3643,31 @@ class AzureDeveloperCliCredential {
|
|
|
3284
3643
|
else {
|
|
3285
3644
|
scopeList = scopes;
|
|
3286
3645
|
}
|
|
3287
|
-
logger$
|
|
3646
|
+
logger$4.getToken.info(`Using the scopes ${scopes}`);
|
|
3288
3647
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
3289
|
-
var _a, _b, _c;
|
|
3648
|
+
var _a, _b, _c, _d;
|
|
3290
3649
|
try {
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3650
|
+
scopeList.forEach((scope) => {
|
|
3651
|
+
ensureValidScopeForDevTimeCreds(scope, logger$4);
|
|
3652
|
+
});
|
|
3653
|
+
const obj = await developerCliCredentialInternals.getAzdAccessToken(scopeList, tenantId, this.timeout);
|
|
3654
|
+
const isNotLoggedInError = ((_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("not logged in, run `azd login` to login")) ||
|
|
3655
|
+
((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("not logged in, run `azd auth login` to login"));
|
|
3656
|
+
const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("azd:(.*)not found")) ||
|
|
3657
|
+
((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'azd' is not recognized"));
|
|
3295
3658
|
if (isNotInstallError || (obj.error && obj.error.code === "ENOENT")) {
|
|
3296
|
-
const error = new CredentialUnavailableError("Azure Developer CLI
|
|
3297
|
-
logger$
|
|
3659
|
+
const error = new CredentialUnavailableError("Azure Developer CLI couldn't be found. To mitigate this issue, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot.");
|
|
3660
|
+
logger$4.getToken.info(formatError(scopes, error));
|
|
3298
3661
|
throw error;
|
|
3299
3662
|
}
|
|
3300
3663
|
if (isNotLoggedInError) {
|
|
3301
|
-
const error = new CredentialUnavailableError("Please run 'azd login' from a command prompt to authenticate before using this credential.");
|
|
3302
|
-
logger$
|
|
3664
|
+
const error = new CredentialUnavailableError("Please run 'azd auth login' from a command prompt to authenticate before using this credential. For more information, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot.");
|
|
3665
|
+
logger$4.getToken.info(formatError(scopes, error));
|
|
3303
3666
|
throw error;
|
|
3304
3667
|
}
|
|
3305
3668
|
try {
|
|
3306
3669
|
const resp = JSON.parse(obj.stdout);
|
|
3307
|
-
logger$
|
|
3670
|
+
logger$4.getToken.info(formatSuccess(scopes));
|
|
3308
3671
|
return {
|
|
3309
3672
|
token: resp.token,
|
|
3310
3673
|
expiresOnTimestamp: new Date(resp.expiresOn).getTime(),
|
|
@@ -3321,7 +3684,7 @@ class AzureDeveloperCliCredential {
|
|
|
3321
3684
|
const error = err.name === "CredentialUnavailableError"
|
|
3322
3685
|
? err
|
|
3323
3686
|
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
|
|
3324
|
-
logger$
|
|
3687
|
+
logger$4.getToken.info(formatError(scopes, error));
|
|
3325
3688
|
throw error;
|
|
3326
3689
|
}
|
|
3327
3690
|
});
|
|
@@ -3329,6 +3692,7 @@ class AzureDeveloperCliCredential {
|
|
|
3329
3692
|
}
|
|
3330
3693
|
|
|
3331
3694
|
// Copyright (c) Microsoft Corporation.
|
|
3695
|
+
// Licensed under the MIT license.
|
|
3332
3696
|
/**
|
|
3333
3697
|
* A shim around ManagedIdentityCredential that adapts it to accept
|
|
3334
3698
|
* `DefaultAzureCredentialOptions`.
|
|
@@ -3339,14 +3703,21 @@ class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
|
|
|
3339
3703
|
// Constructor overload with just the other default options
|
|
3340
3704
|
// Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
|
|
3341
3705
|
constructor(options) {
|
|
3342
|
-
var _a;
|
|
3706
|
+
var _a, _b, _c;
|
|
3343
3707
|
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
|
|
3708
|
+
const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
|
|
3344
3709
|
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
|
|
3710
|
+
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3711
|
+
const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
|
|
3345
3712
|
// ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
|
|
3346
3713
|
if (managedResourceId) {
|
|
3347
3714
|
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
|
|
3348
3715
|
super(managedIdentityResourceIdOptions);
|
|
3349
3716
|
}
|
|
3717
|
+
else if (workloadFile && workloadIdentityClientId) {
|
|
3718
|
+
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId: tenantId });
|
|
3719
|
+
super(workloadIdentityClientId, workloadIdentityCredentialOptions);
|
|
3720
|
+
}
|
|
3350
3721
|
else if (managedIdentityClientId) {
|
|
3351
3722
|
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
|
|
3352
3723
|
super(managedIdentityClientOptions);
|
|
@@ -3356,112 +3727,75 @@ class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
|
|
|
3356
3727
|
}
|
|
3357
3728
|
}
|
|
3358
3729
|
}
|
|
3359
|
-
const defaultCredentials = [
|
|
3360
|
-
EnvironmentCredential,
|
|
3361
|
-
DefaultManagedIdentityCredential,
|
|
3362
|
-
AzureDeveloperCliCredential,
|
|
3363
|
-
AzureCliCredential,
|
|
3364
|
-
AzurePowerShellCredential,
|
|
3365
|
-
];
|
|
3366
3730
|
/**
|
|
3367
|
-
*
|
|
3368
|
-
*
|
|
3731
|
+
* A shim around WorkloadIdentityCredential that adapts it to accept
|
|
3732
|
+
* `DefaultAzureCredentialOptions`.
|
|
3733
|
+
*
|
|
3734
|
+
* @internal
|
|
3369
3735
|
*/
|
|
3370
|
-
class
|
|
3736
|
+
class DefaultWorkloadIdentityCredential extends WorkloadIdentityCredential {
|
|
3737
|
+
// Constructor overload with just the other default options
|
|
3738
|
+
// Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
|
|
3371
3739
|
constructor(options) {
|
|
3372
|
-
|
|
3740
|
+
var _a, _b, _c;
|
|
3741
|
+
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
|
|
3742
|
+
const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
|
|
3743
|
+
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3744
|
+
const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
|
|
3745
|
+
if (workloadFile && workloadIdentityClientId) {
|
|
3746
|
+
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId, clientId: workloadIdentityClientId, tokenFilePath: workloadFile });
|
|
3747
|
+
super(workloadIdentityCredentialOptions);
|
|
3748
|
+
}
|
|
3749
|
+
else if (tenantId) {
|
|
3750
|
+
const workloadIdentityClientTenantOptions = Object.assign(Object.assign({}, options), { tenantId });
|
|
3751
|
+
super(workloadIdentityClientTenantOptions);
|
|
3752
|
+
}
|
|
3753
|
+
else {
|
|
3754
|
+
super(options);
|
|
3755
|
+
}
|
|
3373
3756
|
}
|
|
3374
3757
|
}
|
|
3375
|
-
|
|
3376
|
-
// Copyright (c) Microsoft Corporation.
|
|
3377
|
-
/**
|
|
3378
|
-
* MSAL client assertion client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
|
|
3379
|
-
* @internal
|
|
3380
|
-
*/
|
|
3381
|
-
class MsalClientAssertion extends MsalNode {
|
|
3758
|
+
class DefaultAzureDeveloperCliCredential extends AzureDeveloperCliCredential {
|
|
3382
3759
|
constructor(options) {
|
|
3383
|
-
super(options);
|
|
3384
|
-
this.requiresConfidential = true;
|
|
3385
|
-
this.getAssertion = options.getAssertion;
|
|
3760
|
+
super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.processTimeoutInMs }, options));
|
|
3386
3761
|
}
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
scopes,
|
|
3392
|
-
correlationId: options.correlationId,
|
|
3393
|
-
azureRegion: this.azureRegion,
|
|
3394
|
-
authority: options.authority,
|
|
3395
|
-
claims: options.claims,
|
|
3396
|
-
clientAssertion: assertion,
|
|
3397
|
-
});
|
|
3398
|
-
// The Client Credential flow does not return an account,
|
|
3399
|
-
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
3400
|
-
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
3401
|
-
}
|
|
3402
|
-
catch (err) {
|
|
3403
|
-
let err2 = err;
|
|
3404
|
-
if (err === null || err === undefined) {
|
|
3405
|
-
err2 = new Error(JSON.stringify(err));
|
|
3406
|
-
}
|
|
3407
|
-
else {
|
|
3408
|
-
err2 = coreUtil.isError(err) ? err : new Error(String(err));
|
|
3409
|
-
}
|
|
3410
|
-
throw this.handleError(scopes, err2, options);
|
|
3411
|
-
}
|
|
3762
|
+
}
|
|
3763
|
+
class DefaultAzureCliCredential extends AzureCliCredential {
|
|
3764
|
+
constructor(options) {
|
|
3765
|
+
super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.processTimeoutInMs }, options));
|
|
3412
3766
|
}
|
|
3413
3767
|
}
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3768
|
+
class DefaultAzurePowershellCredential extends AzurePowerShellCredential {
|
|
3769
|
+
constructor(options) {
|
|
3770
|
+
super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.processTimeoutInMs }, options));
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
const defaultCredentials = [
|
|
3774
|
+
EnvironmentCredential,
|
|
3775
|
+
DefaultWorkloadIdentityCredential,
|
|
3776
|
+
DefaultManagedIdentityCredential,
|
|
3777
|
+
DefaultAzureCliCredential,
|
|
3778
|
+
DefaultAzurePowershellCredential,
|
|
3779
|
+
DefaultAzureDeveloperCliCredential,
|
|
3780
|
+
];
|
|
3417
3781
|
/**
|
|
3418
|
-
*
|
|
3782
|
+
* Provides a default {@link ChainedTokenCredential} configuration that should
|
|
3783
|
+
* work for most applications that use the Azure SDK.
|
|
3419
3784
|
*/
|
|
3420
|
-
class
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
* needed to authenticate against Azure Active Directory with a client
|
|
3424
|
-
* assertion provided by the developer through the `getAssertion` function parameter.
|
|
3425
|
-
*
|
|
3426
|
-
* @param tenantId - The Azure Active Directory tenant (directory) ID.
|
|
3427
|
-
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
3428
|
-
* @param getAssertion - A function that retrieves the assertion for the credential to use.
|
|
3429
|
-
* @param options - Options for configuring the client which makes the authentication request.
|
|
3430
|
-
*/
|
|
3431
|
-
constructor(tenantId, clientId, getAssertion, options = {}) {
|
|
3432
|
-
if (!tenantId || !clientId || !getAssertion) {
|
|
3433
|
-
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
|
|
3434
|
-
}
|
|
3435
|
-
this.tenantId = tenantId;
|
|
3436
|
-
this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3437
|
-
this.clientId = clientId;
|
|
3438
|
-
this.options = options;
|
|
3439
|
-
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$4, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
|
|
3440
|
-
}
|
|
3441
|
-
/**
|
|
3442
|
-
* Authenticates with Azure Active Directory and returns an access token if successful.
|
|
3443
|
-
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3444
|
-
*
|
|
3445
|
-
* @param scopes - The list of scopes for which the token will have access.
|
|
3446
|
-
* @param options - The options used to configure any requests this
|
|
3447
|
-
* TokenCredential implementation might make.
|
|
3448
|
-
*/
|
|
3449
|
-
async getToken(scopes, options = {}) {
|
|
3450
|
-
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3451
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
3452
|
-
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3453
|
-
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3454
|
-
});
|
|
3785
|
+
class DefaultAzureCredential extends ChainedTokenCredential {
|
|
3786
|
+
constructor(options) {
|
|
3787
|
+
super(...defaultCredentials.map((ctor) => new ctor(options)));
|
|
3455
3788
|
}
|
|
3456
3789
|
}
|
|
3457
3790
|
|
|
3458
3791
|
// Copyright (c) Microsoft Corporation.
|
|
3792
|
+
// Licensed under the MIT license.
|
|
3459
3793
|
/**
|
|
3460
3794
|
* A call to open(), but mockable
|
|
3461
3795
|
* @internal
|
|
3462
3796
|
*/
|
|
3463
3797
|
const interactiveBrowserMockable = {
|
|
3464
|
-
open
|
|
3798
|
+
open,
|
|
3465
3799
|
};
|
|
3466
3800
|
/**
|
|
3467
3801
|
* This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`
|
|
@@ -3470,182 +3804,106 @@ const interactiveBrowserMockable = {
|
|
|
3470
3804
|
*/
|
|
3471
3805
|
class MsalOpenBrowser extends MsalNode {
|
|
3472
3806
|
constructor(options) {
|
|
3807
|
+
var _a, _b;
|
|
3473
3808
|
super(options);
|
|
3474
|
-
this.logger = credentialLogger("Node.js MSAL Open Browser");
|
|
3475
|
-
this.redirectUri = options.redirectUri;
|
|
3476
3809
|
this.loginHint = options.loginHint;
|
|
3477
|
-
|
|
3478
|
-
this.
|
|
3479
|
-
|
|
3480
|
-
this.port = 80;
|
|
3481
|
-
}
|
|
3482
|
-
this.hostname = url.hostname;
|
|
3483
|
-
}
|
|
3484
|
-
async acquireTokenByCode(request) {
|
|
3485
|
-
return this.publicApp.acquireTokenByCode(request);
|
|
3810
|
+
this.errorTemplate = (_a = options.browserCustomizationOptions) === null || _a === void 0 ? void 0 : _a.errorMessage;
|
|
3811
|
+
this.successTemplate = (_b = options.browserCustomizationOptions) === null || _b === void 0 ? void 0 : _b.successMessage;
|
|
3812
|
+
this.logger = credentialLogger("Node.js MSAL Open Browser");
|
|
3486
3813
|
}
|
|
3487
|
-
doGetToken(scopes, options) {
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
const
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
|
|
3502
|
-
return;
|
|
3503
|
-
}
|
|
3504
|
-
const tokenRequest = {
|
|
3505
|
-
code: url.searchParams.get("code"),
|
|
3506
|
-
redirectUri: this.redirectUri,
|
|
3507
|
-
scopes: scopes,
|
|
3508
|
-
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3509
|
-
codeVerifier: (_a = this.pkceCodes) === null || _a === void 0 ? void 0 : _a.verifier,
|
|
3510
|
-
};
|
|
3511
|
-
this.acquireTokenByCode(tokenRequest)
|
|
3512
|
-
.then((authResponse) => {
|
|
3513
|
-
if (authResponse === null || authResponse === void 0 ? void 0 : authResponse.account) {
|
|
3514
|
-
this.account = msalToPublic(this.clientId, authResponse.account);
|
|
3515
|
-
}
|
|
3516
|
-
const successMessage = `Authentication Complete. You can close the browser and return to the application.`;
|
|
3517
|
-
if (authResponse && authResponse.expiresOn) {
|
|
3518
|
-
const expiresOnTimestamp = authResponse === null || authResponse === void 0 ? void 0 : authResponse.expiresOn.valueOf();
|
|
3519
|
-
res.writeHead(200);
|
|
3520
|
-
res.end(successMessage);
|
|
3521
|
-
this.logger.getToken.info(formatSuccess(scopes));
|
|
3522
|
-
resolve({
|
|
3523
|
-
expiresOnTimestamp,
|
|
3524
|
-
token: authResponse.accessToken,
|
|
3525
|
-
});
|
|
3526
|
-
}
|
|
3527
|
-
else {
|
|
3528
|
-
const errorMessage = formatError(scopes, `${url.searchParams.get("error")}. ${url.searchParams.get("error_description")}`);
|
|
3529
|
-
res.writeHead(500);
|
|
3530
|
-
res.end(errorMessage);
|
|
3531
|
-
this.logger.getToken.info(errorMessage);
|
|
3532
|
-
reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
|
|
3533
|
-
}
|
|
3534
|
-
cleanup();
|
|
3535
|
-
return;
|
|
3536
|
-
})
|
|
3537
|
-
.catch(() => {
|
|
3538
|
-
const errorMessage = formatError(scopes, `${url.searchParams.get("error")}. ${url.searchParams.get("error_description")}`);
|
|
3539
|
-
res.writeHead(500);
|
|
3540
|
-
res.end(errorMessage);
|
|
3541
|
-
this.logger.getToken.info(errorMessage);
|
|
3542
|
-
reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
|
|
3543
|
-
cleanup();
|
|
3544
|
-
});
|
|
3814
|
+
async doGetToken(scopes, options) {
|
|
3815
|
+
var _a;
|
|
3816
|
+
try {
|
|
3817
|
+
const interactiveRequest = {
|
|
3818
|
+
openBrowser: async (url) => {
|
|
3819
|
+
await interactiveBrowserMockable.open(url, { wait: true, newInstance: true });
|
|
3820
|
+
},
|
|
3821
|
+
scopes,
|
|
3822
|
+
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3823
|
+
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3824
|
+
correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
|
|
3825
|
+
loginHint: this.loginHint,
|
|
3826
|
+
errorTemplate: this.errorTemplate,
|
|
3827
|
+
successTemplate: this.successTemplate,
|
|
3545
3828
|
};
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
if (listen) {
|
|
3551
|
-
listen.close();
|
|
3552
|
-
}
|
|
3553
|
-
for (const socket of socketToDestroy) {
|
|
3554
|
-
socket.destroy();
|
|
3555
|
-
}
|
|
3556
|
-
if (server) {
|
|
3557
|
-
server.close();
|
|
3558
|
-
server.stop();
|
|
3559
|
-
}
|
|
3560
|
-
}
|
|
3561
|
-
app.on("connection", (socket) => socketToDestroy.push(socket));
|
|
3562
|
-
app.on("error", (err) => {
|
|
3563
|
-
cleanup();
|
|
3564
|
-
const code = err.code;
|
|
3565
|
-
if (code === "EACCES" || code === "EADDRINUSE") {
|
|
3566
|
-
reject(new CredentialUnavailableError([
|
|
3567
|
-
`InteractiveBrowserCredential: Access denied to port ${this.port}.`,
|
|
3568
|
-
`Try sending a redirect URI with a different port, as follows:`,
|
|
3569
|
-
'`new InteractiveBrowserCredential({ redirectUri: "http://localhost:1337" })`',
|
|
3570
|
-
].join(" ")));
|
|
3829
|
+
if (hasNativeBroker() && this.enableBroker) {
|
|
3830
|
+
this.logger.verbose("Authentication will resume through the broker");
|
|
3831
|
+
if (this.parentWindowHandle) {
|
|
3832
|
+
interactiveRequest.windowHandle = Buffer.from(this.parentWindowHandle);
|
|
3571
3833
|
}
|
|
3572
3834
|
else {
|
|
3573
|
-
|
|
3835
|
+
// error should have been thrown from within the constructor of InteractiveBrowserCredential
|
|
3836
|
+
this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
|
|
3574
3837
|
}
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
const abortSignal = options === null || options === void 0 ? void 0 : options.abortSignal;
|
|
3579
|
-
if (abortSignal) {
|
|
3580
|
-
abortSignal.addEventListener("abort", () => {
|
|
3581
|
-
cleanup();
|
|
3582
|
-
reject(new Error("Aborted"));
|
|
3583
|
-
});
|
|
3838
|
+
if (this.enableMsaPassthrough) {
|
|
3839
|
+
((_a = interactiveRequest.tokenQueryParameters) !== null && _a !== void 0 ? _a : (interactiveRequest.tokenQueryParameters = {}))["msal_request_type"] =
|
|
3840
|
+
"consumer_passthrough";
|
|
3584
3841
|
}
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
const cryptoProvider = new msalNode__namespace.CryptoProvider();
|
|
3595
|
-
// Generate PKCE Codes before starting the authorization flow
|
|
3596
|
-
this.pkceCodes = await cryptoProvider.generatePkceCodes();
|
|
3597
|
-
const authCodeUrlParameters = {
|
|
3598
|
-
scopes: scopeArray,
|
|
3599
|
-
correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
|
|
3600
|
-
redirectUri: this.redirectUri,
|
|
3601
|
-
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3602
|
-
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3603
|
-
loginHint: this.loginHint,
|
|
3604
|
-
codeChallenge: this.pkceCodes.challenge,
|
|
3605
|
-
codeChallengeMethod: "S256", // Use SHA256 Algorithm
|
|
3606
|
-
};
|
|
3607
|
-
const response = await this.publicApp.getAuthCodeUrl(authCodeUrlParameters);
|
|
3608
|
-
try {
|
|
3609
|
-
// A new instance on macOS only which allows it to not hang, does not fix the issue on linux
|
|
3610
|
-
await interactiveBrowserMockable.open(response, { wait: true, newInstance: true });
|
|
3842
|
+
}
|
|
3843
|
+
if (hasNativeBroker() && !this.enableBroker) {
|
|
3844
|
+
this.logger.verbose("Authentication will resume normally without the broker, since it's not enabled");
|
|
3845
|
+
}
|
|
3846
|
+
const result = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenInteractive(interactiveRequest);
|
|
3847
|
+
if (result.fromNativeBroker) {
|
|
3848
|
+
this.logger.verbose(`This result is returned from native broker`);
|
|
3849
|
+
}
|
|
3850
|
+
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
3611
3851
|
}
|
|
3612
|
-
catch (
|
|
3613
|
-
throw
|
|
3852
|
+
catch (err) {
|
|
3853
|
+
throw this.handleError(scopes, err, options);
|
|
3614
3854
|
}
|
|
3615
3855
|
}
|
|
3616
3856
|
}
|
|
3617
3857
|
|
|
3618
3858
|
// Copyright (c) Microsoft Corporation.
|
|
3859
|
+
// Licensed under the MIT license.
|
|
3619
3860
|
const logger$3 = credentialLogger("InteractiveBrowserCredential");
|
|
3620
3861
|
/**
|
|
3621
|
-
* Enables authentication to
|
|
3862
|
+
* Enables authentication to Microsoft Entra ID inside of the web browser
|
|
3622
3863
|
* using the interactive login flow.
|
|
3623
3864
|
*/
|
|
3624
3865
|
class InteractiveBrowserCredential {
|
|
3625
3866
|
/**
|
|
3626
3867
|
* Creates an instance of InteractiveBrowserCredential with the details needed.
|
|
3627
3868
|
*
|
|
3628
|
-
* This credential uses the [Authorization Code Flow](https://
|
|
3869
|
+
* This credential uses the [Authorization Code Flow](https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow).
|
|
3629
3870
|
* On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
|
|
3630
3871
|
* On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
|
|
3631
3872
|
*
|
|
3632
|
-
* For Node.js, if a `clientId` is provided, the
|
|
3633
|
-
* Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://
|
|
3873
|
+
* For Node.js, if a `clientId` is provided, the Microsoft Entra application will need to be configured to have a "Mobile and desktop applications" redirect endpoint.
|
|
3874
|
+
* Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://learn.microsoft.com/azure/active-directory/develop/scenario-desktop-app-registration#redirect-uris).
|
|
3634
3875
|
*
|
|
3635
3876
|
* @param options - Options for configuring the client which makes the authentication requests.
|
|
3636
3877
|
*/
|
|
3637
|
-
constructor(options
|
|
3878
|
+
constructor(options) {
|
|
3879
|
+
var _a, _b, _c;
|
|
3638
3880
|
const redirectUri = typeof options.redirectUri === "function"
|
|
3639
3881
|
? options.redirectUri()
|
|
3640
3882
|
: options.redirectUri || "http://localhost";
|
|
3641
3883
|
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
|
|
3642
|
-
this.additionallyAllowedTenantIds =
|
|
3643
|
-
|
|
3644
|
-
|
|
3884
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3885
|
+
const ibcNodeOptions = options;
|
|
3886
|
+
if ((_a = ibcNodeOptions === null || ibcNodeOptions === void 0 ? void 0 : ibcNodeOptions.brokerOptions) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
3887
|
+
if (!((_b = ibcNodeOptions === null || ibcNodeOptions === void 0 ? void 0 : ibcNodeOptions.brokerOptions) === null || _b === void 0 ? void 0 : _b.parentWindowHandle)) {
|
|
3888
|
+
throw new Error("In order to do WAM authentication, `parentWindowHandle` under `brokerOptions` is a required parameter");
|
|
3889
|
+
}
|
|
3890
|
+
else {
|
|
3891
|
+
this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger: logger$3,
|
|
3892
|
+
redirectUri, browserCustomizationOptions: ibcNodeOptions === null || ibcNodeOptions === void 0 ? void 0 : ibcNodeOptions.browserCustomizationOptions, brokerOptions: {
|
|
3893
|
+
enabled: true,
|
|
3894
|
+
parentWindowHandle: ibcNodeOptions.brokerOptions.parentWindowHandle,
|
|
3895
|
+
legacyEnableMsaPassthrough: (_c = ibcNodeOptions.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough,
|
|
3896
|
+
} }));
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
else {
|
|
3900
|
+
this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger: logger$3,
|
|
3901
|
+
redirectUri, browserCustomizationOptions: ibcNodeOptions === null || ibcNodeOptions === void 0 ? void 0 : ibcNodeOptions.browserCustomizationOptions }));
|
|
3902
|
+
}
|
|
3645
3903
|
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
|
|
3646
3904
|
}
|
|
3647
3905
|
/**
|
|
3648
|
-
* Authenticates with
|
|
3906
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3649
3907
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3650
3908
|
*
|
|
3651
3909
|
* If the user provided the option `disableAutomaticAuthentication`,
|
|
@@ -3658,13 +3916,13 @@ class InteractiveBrowserCredential {
|
|
|
3658
3916
|
*/
|
|
3659
3917
|
async getToken(scopes, options = {}) {
|
|
3660
3918
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3661
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
3919
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$3);
|
|
3662
3920
|
const arrayScopes = ensureScopes(scopes);
|
|
3663
3921
|
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
|
|
3664
3922
|
});
|
|
3665
3923
|
}
|
|
3666
3924
|
/**
|
|
3667
|
-
* Authenticates with
|
|
3925
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3668
3926
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3669
3927
|
*
|
|
3670
3928
|
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
|
|
@@ -3686,6 +3944,7 @@ class InteractiveBrowserCredential {
|
|
|
3686
3944
|
}
|
|
3687
3945
|
|
|
3688
3946
|
// Copyright (c) Microsoft Corporation.
|
|
3947
|
+
// Licensed under the MIT license.
|
|
3689
3948
|
/**
|
|
3690
3949
|
* MSAL device code client. Calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`.
|
|
3691
3950
|
* @internal
|
|
@@ -3705,7 +3964,7 @@ class MsalDeviceCode extends MsalNode {
|
|
|
3705
3964
|
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3706
3965
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3707
3966
|
};
|
|
3708
|
-
const promise = this.
|
|
3967
|
+
const promise = this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByDeviceCode(requestOptions);
|
|
3709
3968
|
const deviceResponse = await this.withCancellation(promise, options === null || options === void 0 ? void 0 : options.abortSignal, () => {
|
|
3710
3969
|
requestOptions.cancel = true;
|
|
3711
3970
|
});
|
|
@@ -3718,6 +3977,7 @@ class MsalDeviceCode extends MsalNode {
|
|
|
3718
3977
|
}
|
|
3719
3978
|
|
|
3720
3979
|
// Copyright (c) Microsoft Corporation.
|
|
3980
|
+
// Licensed under the MIT license.
|
|
3721
3981
|
const logger$2 = credentialLogger("DeviceCodeCredential");
|
|
3722
3982
|
/**
|
|
3723
3983
|
* Method that logs the user code from the DeviceCodeCredential.
|
|
@@ -3727,13 +3987,13 @@ function defaultDeviceCodePromptCallback(deviceCodeInfo) {
|
|
|
3727
3987
|
console.log(deviceCodeInfo.message);
|
|
3728
3988
|
}
|
|
3729
3989
|
/**
|
|
3730
|
-
* Enables authentication to
|
|
3990
|
+
* Enables authentication to Microsoft Entra ID using a device code
|
|
3731
3991
|
* that the user can enter into https://microsoft.com/devicelogin.
|
|
3732
3992
|
*/
|
|
3733
3993
|
class DeviceCodeCredential {
|
|
3734
3994
|
/**
|
|
3735
3995
|
* Creates an instance of DeviceCodeCredential with the details needed
|
|
3736
|
-
* to initiate the device code authorization flow with
|
|
3996
|
+
* to initiate the device code authorization flow with Microsoft Entra ID.
|
|
3737
3997
|
*
|
|
3738
3998
|
* A message will be logged, giving users a code that they can use to authenticate once they go to https://microsoft.com/devicelogin
|
|
3739
3999
|
*
|
|
@@ -3753,12 +4013,12 @@ class DeviceCodeCredential {
|
|
|
3753
4013
|
*/
|
|
3754
4014
|
constructor(options) {
|
|
3755
4015
|
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
|
|
3756
|
-
this.additionallyAllowedTenantIds =
|
|
4016
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3757
4017
|
this.msalFlow = new MsalDeviceCode(Object.assign(Object.assign({}, options), { logger: logger$2, userPromptCallback: (options === null || options === void 0 ? void 0 : options.userPromptCallback) || defaultDeviceCodePromptCallback, tokenCredentialOptions: options || {} }));
|
|
3758
4018
|
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
|
|
3759
4019
|
}
|
|
3760
4020
|
/**
|
|
3761
|
-
* Authenticates with
|
|
4021
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3762
4022
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3763
4023
|
*
|
|
3764
4024
|
* If the user provided the option `disableAutomaticAuthentication`,
|
|
@@ -3771,13 +4031,13 @@ class DeviceCodeCredential {
|
|
|
3771
4031
|
*/
|
|
3772
4032
|
async getToken(scopes, options = {}) {
|
|
3773
4033
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3774
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
4034
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$2);
|
|
3775
4035
|
const arrayScopes = ensureScopes(scopes);
|
|
3776
4036
|
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
|
|
3777
4037
|
});
|
|
3778
4038
|
}
|
|
3779
4039
|
/**
|
|
3780
|
-
* Authenticates with
|
|
4040
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3781
4041
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3782
4042
|
*
|
|
3783
4043
|
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
|
|
@@ -3796,6 +4056,7 @@ class DeviceCodeCredential {
|
|
|
3796
4056
|
}
|
|
3797
4057
|
|
|
3798
4058
|
// Copyright (c) Microsoft Corporation.
|
|
4059
|
+
// Licensed under the MIT license.
|
|
3799
4060
|
/**
|
|
3800
4061
|
* This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`
|
|
3801
4062
|
* to trigger the authentication flow, and then respond based on the values obtained from the redirect callback
|
|
@@ -3813,19 +4074,21 @@ class MsalAuthorizationCode extends MsalNode {
|
|
|
3813
4074
|
}
|
|
3814
4075
|
async getAuthCodeUrl(options) {
|
|
3815
4076
|
await this.init();
|
|
3816
|
-
return
|
|
4077
|
+
return this.getApp("confidentialFirst", options.enableCae).getAuthCodeUrl({
|
|
4078
|
+
scopes: options.scopes,
|
|
4079
|
+
redirectUri: options.redirectUri,
|
|
4080
|
+
});
|
|
3817
4081
|
}
|
|
3818
4082
|
async doGetToken(scopes, options) {
|
|
3819
|
-
var _a;
|
|
3820
4083
|
try {
|
|
3821
|
-
const result = await
|
|
4084
|
+
const result = await this.getApp("confidentialFirst", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByCode({
|
|
3822
4085
|
scopes,
|
|
3823
4086
|
redirectUri: this.redirectUri,
|
|
3824
4087
|
code: this.authorizationCode,
|
|
3825
4088
|
correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
|
|
3826
4089
|
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3827
4090
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3828
|
-
})
|
|
4091
|
+
});
|
|
3829
4092
|
// The Client Credential flow does not return an account,
|
|
3830
4093
|
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
3831
4094
|
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
@@ -3837,13 +4100,14 @@ class MsalAuthorizationCode extends MsalNode {
|
|
|
3837
4100
|
}
|
|
3838
4101
|
|
|
3839
4102
|
// Copyright (c) Microsoft Corporation.
|
|
4103
|
+
// Licensed under the MIT license.
|
|
3840
4104
|
const logger$1 = credentialLogger("AuthorizationCodeCredential");
|
|
3841
4105
|
/**
|
|
3842
|
-
* Enables authentication to
|
|
4106
|
+
* Enables authentication to Microsoft Entra ID using an authorization code
|
|
3843
4107
|
* that was obtained through the authorization code flow, described in more detail
|
|
3844
|
-
* in the
|
|
4108
|
+
* in the Microsoft Entra ID documentation:
|
|
3845
4109
|
*
|
|
3846
|
-
* https://
|
|
4110
|
+
* https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow
|
|
3847
4111
|
*/
|
|
3848
4112
|
class AuthorizationCodeCredential {
|
|
3849
4113
|
/**
|
|
@@ -3868,13 +4132,13 @@ class AuthorizationCodeCredential {
|
|
|
3868
4132
|
}
|
|
3869
4133
|
// TODO: Validate tenant if provided
|
|
3870
4134
|
this.tenantId = tenantId;
|
|
3871
|
-
this.additionallyAllowedTenantIds =
|
|
4135
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3872
4136
|
this.msalFlow = new MsalAuthorizationCode(Object.assign(Object.assign({}, options), { clientSecret,
|
|
3873
4137
|
clientId,
|
|
3874
4138
|
tenantId, tokenCredentialOptions: options || {}, logger: logger$1, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
|
|
3875
4139
|
}
|
|
3876
4140
|
/**
|
|
3877
|
-
* Authenticates with
|
|
4141
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3878
4142
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3879
4143
|
*
|
|
3880
4144
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -3892,6 +4156,7 @@ class AuthorizationCodeCredential {
|
|
|
3892
4156
|
}
|
|
3893
4157
|
|
|
3894
4158
|
// Copyright (c) Microsoft Corporation.
|
|
4159
|
+
// Licensed under the MIT license.
|
|
3895
4160
|
/**
|
|
3896
4161
|
* MSAL on behalf of flow. Calls to MSAL's confidential application's `acquireTokenOnBehalfOf` during `doGetToken`.
|
|
3897
4162
|
* @internal
|
|
@@ -3929,7 +4194,7 @@ class MsalOnBehalfOf extends MsalNode {
|
|
|
3929
4194
|
}
|
|
3930
4195
|
async doGetToken(scopes, options = {}) {
|
|
3931
4196
|
try {
|
|
3932
|
-
const result = await this.
|
|
4197
|
+
const result = await this.getApp("confidential", options.enableCae).acquireTokenOnBehalfOf({
|
|
3933
4198
|
scopes,
|
|
3934
4199
|
correlationId: options.correlationId,
|
|
3935
4200
|
authority: options.authority,
|
|
@@ -3945,10 +4210,11 @@ class MsalOnBehalfOf extends MsalNode {
|
|
|
3945
4210
|
}
|
|
3946
4211
|
|
|
3947
4212
|
// Copyright (c) Microsoft Corporation.
|
|
4213
|
+
// Licensed under the MIT license.
|
|
3948
4214
|
const credentialName = "OnBehalfOfCredential";
|
|
3949
4215
|
const logger = credentialLogger(credentialName);
|
|
3950
4216
|
/**
|
|
3951
|
-
* Enables authentication to
|
|
4217
|
+
* Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
|
|
3952
4218
|
*/
|
|
3953
4219
|
class OnBehalfOfCredential {
|
|
3954
4220
|
constructor(options) {
|
|
@@ -3960,11 +4226,11 @@ class OnBehalfOfCredential {
|
|
|
3960
4226
|
throw new Error(`${credentialName}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`);
|
|
3961
4227
|
}
|
|
3962
4228
|
this.tenantId = tenantId;
|
|
3963
|
-
this.additionallyAllowedTenantIds =
|
|
4229
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(additionallyAllowedTenantIds);
|
|
3964
4230
|
this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger, tokenCredentialOptions: this.options }));
|
|
3965
4231
|
}
|
|
3966
4232
|
/**
|
|
3967
|
-
* Authenticates with
|
|
4233
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3968
4234
|
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3969
4235
|
*
|
|
3970
4236
|
* @param scopes - The list of scopes for which the token will have access.
|
|
@@ -3972,7 +4238,7 @@ class OnBehalfOfCredential {
|
|
|
3972
4238
|
*/
|
|
3973
4239
|
async getToken(scopes, options = {}) {
|
|
3974
4240
|
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
|
|
3975
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
4241
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger);
|
|
3976
4242
|
const arrayScopes = ensureScopes(scopes);
|
|
3977
4243
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3978
4244
|
});
|
|
@@ -3980,6 +4246,7 @@ class OnBehalfOfCredential {
|
|
|
3980
4246
|
}
|
|
3981
4247
|
|
|
3982
4248
|
// Copyright (c) Microsoft Corporation.
|
|
4249
|
+
// Licensed under the MIT license.
|
|
3983
4250
|
/**
|
|
3984
4251
|
* Returns a new instance of the {@link DefaultAzureCredential}.
|
|
3985
4252
|
*/
|
|
@@ -3994,6 +4261,7 @@ exports.AuthenticationErrorName = AuthenticationErrorName;
|
|
|
3994
4261
|
exports.AuthenticationRequiredError = AuthenticationRequiredError;
|
|
3995
4262
|
exports.AuthorizationCodeCredential = AuthorizationCodeCredential;
|
|
3996
4263
|
exports.AzureCliCredential = AzureCliCredential;
|
|
4264
|
+
exports.AzureDeveloperCliCredential = AzureDeveloperCliCredential;
|
|
3997
4265
|
exports.AzurePowerShellCredential = AzurePowerShellCredential;
|
|
3998
4266
|
exports.ChainedTokenCredential = ChainedTokenCredential;
|
|
3999
4267
|
exports.ClientAssertionCredential = ClientAssertionCredential;
|
|
@@ -4009,9 +4277,10 @@ exports.ManagedIdentityCredential = ManagedIdentityCredential;
|
|
|
4009
4277
|
exports.OnBehalfOfCredential = OnBehalfOfCredential;
|
|
4010
4278
|
exports.UsernamePasswordCredential = UsernamePasswordCredential;
|
|
4011
4279
|
exports.VisualStudioCodeCredential = VisualStudioCodeCredential;
|
|
4280
|
+
exports.WorkloadIdentityCredential = WorkloadIdentityCredential;
|
|
4012
4281
|
exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord;
|
|
4013
4282
|
exports.getDefaultAzureCredential = getDefaultAzureCredential;
|
|
4014
|
-
exports.logger = logger$
|
|
4283
|
+
exports.logger = logger$n;
|
|
4015
4284
|
exports.serializeAuthenticationRecord = serializeAuthenticationRecord;
|
|
4016
4285
|
exports.useIdentityPlugin = useIdentityPlugin;
|
|
4017
4286
|
//# sourceMappingURL=index.js.map
|