@azure/identity 2.1.0-beta.1 → 2.1.1-alpha.20220712.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/README.md +66 -33
- package/dist/index.js +526 -389
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +71 -46
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/constants.js +4 -0
- package/dist-esm/src/constants.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +4 -3
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +34 -34
- package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredential.js +3 -3
- package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
- package/dist-esm/src/credentials/chainedTokenCredential.js +28 -33
- package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientAssertionCredential.browser.js +22 -0
- package/dist-esm/src/credentials/clientAssertionCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/clientAssertionCredential.js +45 -0
- package/dist-esm/src/credentials/clientAssertionCredential.js.map +1 -0
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.js +7 -4
- package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.browser.js +31 -38
- package/dist-esm/src/credentials/clientSecretCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.js +2 -2
- package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js +16 -29
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +3 -3
- package/dist-esm/src/credentials/deviceCodeCredential.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/interactiveBrowserCredential.browser.js +3 -3
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.js +3 -3
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js +77 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +38 -49
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +20 -13
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredential.js +2 -23
- 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 +5 -6
- package/dist-esm/src/credentials/usernamePasswordCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.js +2 -2
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
- package/dist-esm/src/errors.js.map +1 -1
- package/dist-esm/src/index.js +1 -0
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/msal/browserFlows/msalAuthCode.js.map +1 -1
- package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js +1 -1
- 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/msalAuthorizationCode.js +2 -2
- package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientAssertion.js +42 -0
- package/dist-esm/src/msal/nodeFlows/msalClientAssertion.js.map +1 -0
- package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js +8 -3
- package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientSecret.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js +0 -2
- package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js +19 -2
- package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js +2 -1
- package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js.map +1 -1
- package/dist-esm/src/msal/utils.js +1 -1
- package/dist-esm/src/msal/utils.js.map +1 -1
- package/dist-esm/src/tokenCredentialOptions.js.map +1 -1
- package/dist-esm/src/util/logging.js.map +1 -1
- package/dist-esm/src/util/tracing.js +5 -36
- package/dist-esm/src/util/tracing.js.map +1 -1
- package/package.json +31 -25
- package/types/identity.d.ts +162 -57
- package/CHANGELOG.md +0 -530
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var msalNode = require('@azure/msal-node');
|
|
6
|
-
var coreTracing = require('@azure/core-tracing');
|
|
7
6
|
var coreClient = require('@azure/core-client');
|
|
8
7
|
var coreUtil = require('@azure/core-util');
|
|
9
8
|
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
|
10
9
|
var abortController = require('@azure/abort-controller');
|
|
11
|
-
var
|
|
10
|
+
var coreTracing = require('@azure/core-tracing');
|
|
11
|
+
var logger$m = require('@azure/logger');
|
|
12
12
|
var msalCommon = require('@azure/msal-common');
|
|
13
13
|
var uuid = require('uuid');
|
|
14
14
|
var fs = require('fs');
|
|
@@ -186,6 +186,10 @@ function getIdentityTokenEndpointSuffix(tenantId) {
|
|
|
186
186
|
|
|
187
187
|
// Copyright (c) Microsoft Corporation.
|
|
188
188
|
// Licensed under the MIT license.
|
|
189
|
+
/**
|
|
190
|
+
* Current version of the `@azure/identity` package.
|
|
191
|
+
*/
|
|
192
|
+
const SDK_VERSION = `2.1.1`;
|
|
189
193
|
/**
|
|
190
194
|
* The default client ID for authentication
|
|
191
195
|
* @internal
|
|
@@ -231,49 +235,17 @@ const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
|
|
|
231
235
|
* Creates a span using the global tracer.
|
|
232
236
|
* @internal
|
|
233
237
|
*/
|
|
234
|
-
const
|
|
235
|
-
packagePrefix: "",
|
|
238
|
+
const tracingClient = coreTracing.createTracingClient({
|
|
236
239
|
namespace: "Microsoft.AAD",
|
|
240
|
+
packageName: "@azure/identity",
|
|
241
|
+
packageVersion: SDK_VERSION,
|
|
237
242
|
});
|
|
238
|
-
/**
|
|
239
|
-
* From: https://github.com/Azure/azure-sdk-for-js/blob/46139daa3317a0d12e8b55b02b9d9cdf1b2e762a/sdk/appconfiguration/app-configuration/src/internal/tracingHelpers.ts
|
|
240
|
-
* Traces an operation and properly handles reporting start, end and errors for a given span
|
|
241
|
-
*
|
|
242
|
-
* @param operationName - Name of a method in the TClient type
|
|
243
|
-
* @param options - An options class, typically derived from \@azure/core-rest-pipeline/RequestOptionsBase
|
|
244
|
-
* @param fn - The function to call with an options class that properly propagates the span context
|
|
245
|
-
*
|
|
246
|
-
* @internal
|
|
247
|
-
*/
|
|
248
|
-
async function trace(operationName, options, fn, createSpanFn = createSpan) {
|
|
249
|
-
const { updatedOptions, span } = createSpanFn(operationName, options);
|
|
250
|
-
try {
|
|
251
|
-
// NOTE: we really do need to await on this function here so we can handle any exceptions thrown and properly
|
|
252
|
-
// close the span.
|
|
253
|
-
const result = await fn(updatedOptions, span);
|
|
254
|
-
// otel 0.16+ needs this or else the code ends up being set as UNSET
|
|
255
|
-
span.setStatus({
|
|
256
|
-
code: coreTracing.SpanStatusCode.OK,
|
|
257
|
-
});
|
|
258
|
-
return result;
|
|
259
|
-
}
|
|
260
|
-
catch (err) {
|
|
261
|
-
span.setStatus({
|
|
262
|
-
code: coreTracing.SpanStatusCode.ERROR,
|
|
263
|
-
message: err.message,
|
|
264
|
-
});
|
|
265
|
-
throw err;
|
|
266
|
-
}
|
|
267
|
-
finally {
|
|
268
|
-
span.end();
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
243
|
|
|
272
244
|
// Copyright (c) Microsoft Corporation.
|
|
273
245
|
/**
|
|
274
246
|
* The AzureLogger used for all clients within the identity package
|
|
275
247
|
*/
|
|
276
|
-
const logger$
|
|
248
|
+
const logger$l = logger$m.createClientLogger("identity");
|
|
277
249
|
/**
|
|
278
250
|
* 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.
|
|
279
251
|
* @param supportedEnvVars - List of environment variable names
|
|
@@ -313,7 +285,7 @@ function formatError(scope, error) {
|
|
|
313
285
|
* `[title] => [message]`
|
|
314
286
|
*
|
|
315
287
|
*/
|
|
316
|
-
function credentialLoggerInstance(title, parent, log = logger$
|
|
288
|
+
function credentialLoggerInstance(title, parent, log = logger$l) {
|
|
317
289
|
const fullTitle = parent ? `${parent.fullTitle} ${title}` : title;
|
|
318
290
|
function info(message) {
|
|
319
291
|
log.info(`${fullTitle} =>`, message);
|
|
@@ -338,7 +310,7 @@ function credentialLoggerInstance(title, parent, log = logger$j) {
|
|
|
338
310
|
* `[title] => getToken() => [message]`
|
|
339
311
|
*
|
|
340
312
|
*/
|
|
341
|
-
function credentialLogger(title, log = logger$
|
|
313
|
+
function credentialLogger(title, log = logger$l) {
|
|
342
314
|
const credLogger = credentialLoggerInstance(title, undefined, log);
|
|
343
315
|
return Object.assign(Object.assign({}, credLogger), { parent: log, getToken: credentialLoggerInstance("=> getToken()", credLogger, log) });
|
|
344
316
|
}
|
|
@@ -367,8 +339,8 @@ function getIdentityClientAuthorityHost(options) {
|
|
|
367
339
|
*/
|
|
368
340
|
class IdentityClient extends coreClient.ServiceClient {
|
|
369
341
|
constructor(options) {
|
|
370
|
-
var _a;
|
|
371
|
-
const packageDetails = `azsdk-js-identity
|
|
342
|
+
var _a, _b;
|
|
343
|
+
const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;
|
|
372
344
|
const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
|
|
373
345
|
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
|
|
374
346
|
: `${packageDetails}`;
|
|
@@ -383,9 +355,10 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
383
355
|
}, baseUri }));
|
|
384
356
|
this.authorityHost = baseUri;
|
|
385
357
|
this.abortControllers = new Map();
|
|
358
|
+
this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
|
|
386
359
|
}
|
|
387
360
|
async sendTokenRequest(request, expiresOnParser) {
|
|
388
|
-
logger$
|
|
361
|
+
logger$l.info(`IdentityClient: sending token request to [${request.url}]`);
|
|
389
362
|
const response = await this.sendRequest(request);
|
|
390
363
|
expiresOnParser =
|
|
391
364
|
expiresOnParser ||
|
|
@@ -397,6 +370,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
397
370
|
if (!parsedBody.access_token) {
|
|
398
371
|
return null;
|
|
399
372
|
}
|
|
373
|
+
this.logIdentifiers(response);
|
|
400
374
|
const token = {
|
|
401
375
|
accessToken: {
|
|
402
376
|
token: parsedBody.access_token,
|
|
@@ -404,21 +378,20 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
404
378
|
},
|
|
405
379
|
refreshToken: parsedBody.refresh_token,
|
|
406
380
|
};
|
|
407
|
-
logger$
|
|
381
|
+
logger$l.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
|
|
408
382
|
return token;
|
|
409
383
|
}
|
|
410
384
|
else {
|
|
411
385
|
const error = new AuthenticationError(response.status, response.bodyAsText);
|
|
412
|
-
logger$
|
|
386
|
+
logger$l.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
|
|
413
387
|
throw error;
|
|
414
388
|
}
|
|
415
389
|
}
|
|
416
|
-
async refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, expiresOnParser, options) {
|
|
390
|
+
async refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, expiresOnParser, options = {}) {
|
|
417
391
|
if (refreshToken === undefined) {
|
|
418
392
|
return null;
|
|
419
393
|
}
|
|
420
|
-
logger$
|
|
421
|
-
const { span, updatedOptions } = createSpan("IdentityClient-refreshAccessToken", options);
|
|
394
|
+
logger$l.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
|
|
422
395
|
const refreshParams = {
|
|
423
396
|
grant_type: "refresh_token",
|
|
424
397
|
client_id: clientId,
|
|
@@ -429,48 +402,39 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
429
402
|
refreshParams.client_secret = clientSecret;
|
|
430
403
|
}
|
|
431
404
|
const query = new URLSearchParams(refreshParams);
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
const response = await this.sendTokenRequest(request, expiresOnParser);
|
|
446
|
-
logger$j.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
|
|
447
|
-
return response;
|
|
448
|
-
}
|
|
449
|
-
catch (err) {
|
|
450
|
-
if (err.name === AuthenticationErrorName &&
|
|
451
|
-
err.errorResponse.error === "interaction_required") {
|
|
452
|
-
// It's likely that the refresh token has expired, so
|
|
453
|
-
// return null so that the credential implementation will
|
|
454
|
-
// initiate the authentication flow again.
|
|
455
|
-
logger$j.info(`IdentityClient: interaction required for client ID: ${clientId}`);
|
|
456
|
-
span.setStatus({
|
|
457
|
-
code: coreTracing.SpanStatusCode.ERROR,
|
|
458
|
-
message: err.message,
|
|
405
|
+
return tracingClient.withSpan("IdentityClient.refreshAccessToken", options, async (updatedOptions) => {
|
|
406
|
+
try {
|
|
407
|
+
const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);
|
|
408
|
+
const request = coreRestPipeline.createPipelineRequest({
|
|
409
|
+
url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,
|
|
410
|
+
method: "POST",
|
|
411
|
+
body: query.toString(),
|
|
412
|
+
abortSignal: options.abortSignal,
|
|
413
|
+
headers: coreRestPipeline.createHttpHeaders({
|
|
414
|
+
Accept: "application/json",
|
|
415
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
416
|
+
}),
|
|
417
|
+
tracingOptions: updatedOptions.tracingOptions,
|
|
459
418
|
});
|
|
460
|
-
|
|
419
|
+
const response = await this.sendTokenRequest(request, expiresOnParser);
|
|
420
|
+
logger$l.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
|
|
421
|
+
return response;
|
|
461
422
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
423
|
+
catch (err) {
|
|
424
|
+
if (err.name === AuthenticationErrorName &&
|
|
425
|
+
err.errorResponse.error === "interaction_required") {
|
|
426
|
+
// It's likely that the refresh token has expired, so
|
|
427
|
+
// return null so that the credential implementation will
|
|
428
|
+
// initiate the authentication flow again.
|
|
429
|
+
logger$l.info(`IdentityClient: interaction required for client ID: ${clientId}`);
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
logger$l.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`);
|
|
434
|
+
throw err;
|
|
435
|
+
}
|
|
469
436
|
}
|
|
470
|
-
}
|
|
471
|
-
finally {
|
|
472
|
-
span.end();
|
|
473
|
-
}
|
|
437
|
+
});
|
|
474
438
|
}
|
|
475
439
|
// Here is a custom layer that allows us to abort requests that go through MSAL,
|
|
476
440
|
// since MSAL doesn't allow us to pass options all the way through.
|
|
@@ -518,6 +482,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
518
482
|
abortSignal: this.generateAbortSignal(noCorrelationId),
|
|
519
483
|
});
|
|
520
484
|
const response = await this.sendRequest(request);
|
|
485
|
+
this.logIdentifiers(response);
|
|
521
486
|
return {
|
|
522
487
|
body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
|
|
523
488
|
headers: response.headers.toJSON(),
|
|
@@ -534,12 +499,45 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
534
499
|
abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),
|
|
535
500
|
});
|
|
536
501
|
const response = await this.sendRequest(request);
|
|
502
|
+
this.logIdentifiers(response);
|
|
537
503
|
return {
|
|
538
504
|
body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
|
|
539
505
|
headers: response.headers.toJSON(),
|
|
540
506
|
status: response.status,
|
|
541
507
|
};
|
|
542
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* If allowLoggingAccountIdentifiers was set on the constructor options
|
|
511
|
+
* we try to log the account identifiers by parsing the received access token.
|
|
512
|
+
*
|
|
513
|
+
* The account identifiers we try to log are:
|
|
514
|
+
* - `appid`: The application or Client Identifier.
|
|
515
|
+
* - `upn`: User Principal Name.
|
|
516
|
+
* - It might not be available in some authentication scenarios.
|
|
517
|
+
* - If it's not available, we put a placeholder: "No User Principal Name available".
|
|
518
|
+
* - `tid`: Tenant Identifier.
|
|
519
|
+
* - `oid`: Object Identifier of the authenticated user.
|
|
520
|
+
*/
|
|
521
|
+
logIdentifiers(response) {
|
|
522
|
+
if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const unavailableUpn = "No User Principal Name available";
|
|
526
|
+
try {
|
|
527
|
+
const parsed = response.parsedBody || JSON.parse(response.bodyAsText);
|
|
528
|
+
const accessToken = parsed.access_token;
|
|
529
|
+
if (!accessToken) {
|
|
530
|
+
// Without an access token allowLoggingAccountIdentifiers isn't useful.
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const base64Metadata = accessToken.split(".")[1];
|
|
534
|
+
const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8"));
|
|
535
|
+
logger$l.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`);
|
|
536
|
+
}
|
|
537
|
+
catch (e) {
|
|
538
|
+
logger$l.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
543
541
|
}
|
|
544
542
|
|
|
545
543
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -953,6 +951,9 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
953
951
|
this.msalConfig = this.defaultNodeMsalConfig(options);
|
|
954
952
|
this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
|
|
955
953
|
this.clientId = this.msalConfig.auth.clientId;
|
|
954
|
+
if (options === null || options === void 0 ? void 0 : options.getAssertion) {
|
|
955
|
+
this.getAssertion = options.getAssertion;
|
|
956
|
+
}
|
|
956
957
|
// If persistence has been configured
|
|
957
958
|
if (persistenceProvider !== undefined && ((_a = options.tokenCachePersistenceOptions) === null || _a === void 0 ? void 0 : _a.enabled)) {
|
|
958
959
|
this.createCachePlugin = () => persistenceProvider(options.tokenCachePersistenceOptions);
|
|
@@ -978,7 +979,7 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
978
979
|
const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
|
|
979
980
|
this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
|
|
980
981
|
const authority = getAuthority(tenantId, this.authorityHost);
|
|
981
|
-
this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority }));
|
|
982
|
+
this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
|
|
982
983
|
let clientCapabilities = ["cp1"];
|
|
983
984
|
if (process.env.AZURE_IDENTITY_DISABLE_CP1) {
|
|
984
985
|
clientCapabilities = [];
|
|
@@ -1019,6 +1020,9 @@ class MsalNode extends MsalBaseUtilities {
|
|
|
1019
1020
|
};
|
|
1020
1021
|
}
|
|
1021
1022
|
this.publicApp = new msalNode__namespace.PublicClientApplication(this.msalConfig);
|
|
1023
|
+
if (this.getAssertion) {
|
|
1024
|
+
this.msalConfig.auth.clientAssertion = await this.getAssertion();
|
|
1025
|
+
}
|
|
1022
1026
|
// The confidential client requires either a secret, assertion or certificate.
|
|
1023
1027
|
if (this.msalConfig.auth.clientSecret ||
|
|
1024
1028
|
this.msalConfig.auth.clientAssertion ||
|
|
@@ -1115,6 +1119,17 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
1115
1119
|
options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || this.generateUuid();
|
|
1116
1120
|
await this.init(options);
|
|
1117
1121
|
try {
|
|
1122
|
+
// MSAL now caches tokens based on their claims,
|
|
1123
|
+
// so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
|
|
1124
|
+
// This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
|
|
1125
|
+
const optionsClaims = options.claims;
|
|
1126
|
+
if (optionsClaims) {
|
|
1127
|
+
this.cachedClaims = optionsClaims;
|
|
1128
|
+
}
|
|
1129
|
+
if (this.cachedClaims && !optionsClaims) {
|
|
1130
|
+
options.claims = this.cachedClaims;
|
|
1131
|
+
}
|
|
1132
|
+
// We don't return the promise since we want to catch errors right here.
|
|
1118
1133
|
return await this.getTokenSilent(scopes, options);
|
|
1119
1134
|
}
|
|
1120
1135
|
catch (err) {
|
|
@@ -1137,7 +1152,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
1137
1152
|
// Copyright (c) Microsoft Corporation.
|
|
1138
1153
|
const CommonTenantId = "common";
|
|
1139
1154
|
const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
|
|
1140
|
-
const logger$
|
|
1155
|
+
const logger$k = credentialLogger("VisualStudioCodeCredential");
|
|
1141
1156
|
let findCredentials = undefined;
|
|
1142
1157
|
const vsCodeCredentialControl = {
|
|
1143
1158
|
setVsCodeCredentialFinder(finder) {
|
|
@@ -1190,7 +1205,7 @@ function getPropertyFromVSCode(property) {
|
|
|
1190
1205
|
}
|
|
1191
1206
|
}
|
|
1192
1207
|
catch (e) {
|
|
1193
|
-
logger$
|
|
1208
|
+
logger$k.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
|
|
1194
1209
|
return;
|
|
1195
1210
|
}
|
|
1196
1211
|
}
|
|
@@ -1218,7 +1233,7 @@ class VisualStudioCodeCredential {
|
|
|
1218
1233
|
const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
|
|
1219
1234
|
this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
|
|
1220
1235
|
if (options && options.tenantId) {
|
|
1221
|
-
checkTenantId(logger$
|
|
1236
|
+
checkTenantId(logger$k, options.tenantId);
|
|
1222
1237
|
this.tenantId = options.tenantId;
|
|
1223
1238
|
}
|
|
1224
1239
|
else {
|
|
@@ -1270,7 +1285,7 @@ class VisualStudioCodeCredential {
|
|
|
1270
1285
|
// Check to make sure the scope we get back is a valid scope
|
|
1271
1286
|
if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
1272
1287
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
1273
|
-
logger$
|
|
1288
|
+
logger$k.getToken.info(formatError(scopes, error));
|
|
1274
1289
|
throw error;
|
|
1275
1290
|
}
|
|
1276
1291
|
if (scopeString.indexOf("offline_access") < 0) {
|
|
@@ -1290,18 +1305,18 @@ class VisualStudioCodeCredential {
|
|
|
1290
1305
|
if (refreshToken) {
|
|
1291
1306
|
const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
|
|
1292
1307
|
if (tokenResponse) {
|
|
1293
|
-
logger$
|
|
1308
|
+
logger$k.getToken.info(formatSuccess(scopes));
|
|
1294
1309
|
return tokenResponse.accessToken;
|
|
1295
1310
|
}
|
|
1296
1311
|
else {
|
|
1297
1312
|
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.");
|
|
1298
|
-
logger$
|
|
1313
|
+
logger$k.getToken.info(formatError(scopes, error));
|
|
1299
1314
|
throw error;
|
|
1300
1315
|
}
|
|
1301
1316
|
}
|
|
1302
1317
|
else {
|
|
1303
1318
|
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.");
|
|
1304
|
-
logger$
|
|
1319
|
+
logger$k.getToken.info(formatError(scopes, error));
|
|
1305
1320
|
throw error;
|
|
1306
1321
|
}
|
|
1307
1322
|
}
|
|
@@ -1352,7 +1367,7 @@ function useIdentityPlugin(plugin) {
|
|
|
1352
1367
|
/**
|
|
1353
1368
|
* @internal
|
|
1354
1369
|
*/
|
|
1355
|
-
const logger$
|
|
1370
|
+
const logger$j = credentialLogger("ChainedTokenCredential");
|
|
1356
1371
|
/**
|
|
1357
1372
|
* Enables multiple `TokenCredential` implementations to be tried in order
|
|
1358
1373
|
* until one of the getToken methods returns an access token.
|
|
@@ -1391,42 +1406,38 @@ class ChainedTokenCredential {
|
|
|
1391
1406
|
* @param options - The options used to configure any requests this
|
|
1392
1407
|
* `TokenCredential` implementation might make.
|
|
1393
1408
|
*/
|
|
1394
|
-
async getToken(scopes, options) {
|
|
1409
|
+
async getToken(scopes, options = {}) {
|
|
1395
1410
|
let token = null;
|
|
1396
1411
|
let successfulCredentialName = "";
|
|
1397
1412
|
const errors = [];
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
catch (err) {
|
|
1405
|
-
if (err.name === "CredentialUnavailableError" ||
|
|
1406
|
-
err.name === "AuthenticationRequiredError") {
|
|
1407
|
-
errors.push(err);
|
|
1413
|
+
return tracingClient.withSpan("ChainedTokenCredential.getToken", options, async (updatedOptions) => {
|
|
1414
|
+
for (let i = 0; i < this._sources.length && token === null; i++) {
|
|
1415
|
+
try {
|
|
1416
|
+
token = await this._sources[i].getToken(scopes, updatedOptions);
|
|
1417
|
+
successfulCredentialName = this._sources[i].constructor.name;
|
|
1408
1418
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1419
|
+
catch (err) {
|
|
1420
|
+
if (err.name === "CredentialUnavailableError" ||
|
|
1421
|
+
err.name === "AuthenticationRequiredError") {
|
|
1422
|
+
errors.push(err);
|
|
1423
|
+
}
|
|
1424
|
+
else {
|
|
1425
|
+
logger$j.getToken.info(formatError(scopes, err));
|
|
1426
|
+
throw err;
|
|
1427
|
+
}
|
|
1412
1428
|
}
|
|
1413
1429
|
}
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
logger$h.getToken.info(`Result for ${successfulCredentialName}: ${formatSuccess(scopes)}`);
|
|
1426
|
-
if (token === null) {
|
|
1427
|
-
throw new CredentialUnavailableError("Failed to retrieve a valid token");
|
|
1428
|
-
}
|
|
1429
|
-
return token;
|
|
1430
|
+
if (!token && errors.length > 0) {
|
|
1431
|
+
const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed.");
|
|
1432
|
+
logger$j.getToken.info(formatError(scopes, err));
|
|
1433
|
+
throw err;
|
|
1434
|
+
}
|
|
1435
|
+
logger$j.getToken.info(`Result for ${successfulCredentialName}: ${formatSuccess(scopes)}`);
|
|
1436
|
+
if (token === null) {
|
|
1437
|
+
throw new CredentialUnavailableError("Failed to retrieve a valid token");
|
|
1438
|
+
}
|
|
1439
|
+
return token;
|
|
1440
|
+
});
|
|
1430
1441
|
}
|
|
1431
1442
|
}
|
|
1432
1443
|
|
|
@@ -1500,7 +1511,7 @@ const cliCredentialInternals = {
|
|
|
1500
1511
|
});
|
|
1501
1512
|
},
|
|
1502
1513
|
};
|
|
1503
|
-
const logger$
|
|
1514
|
+
const logger$i = credentialLogger("AzureCliCredential");
|
|
1504
1515
|
/**
|
|
1505
1516
|
* This credential will use the currently logged-in user login information
|
|
1506
1517
|
* via the Azure CLI ('az') commandline tool.
|
|
@@ -1527,56 +1538,57 @@ class AzureCliCredential {
|
|
|
1527
1538
|
* @param options - The options used to configure any requests this
|
|
1528
1539
|
* TokenCredential implementation might make.
|
|
1529
1540
|
*/
|
|
1530
|
-
async getToken(scopes, options) {
|
|
1541
|
+
async getToken(scopes, options = {}) {
|
|
1531
1542
|
const tenantId = processMultiTenantRequest(this.tenantId, options);
|
|
1532
1543
|
if (tenantId) {
|
|
1533
|
-
checkTenantId(logger$
|
|
1544
|
+
checkTenantId(logger$i, tenantId);
|
|
1534
1545
|
}
|
|
1535
1546
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
1536
|
-
logger$
|
|
1537
|
-
ensureValidScope(scope, logger$
|
|
1547
|
+
logger$i.getToken.info(`Using the scope ${scope}`);
|
|
1548
|
+
ensureValidScope(scope, logger$i);
|
|
1538
1549
|
const resource = getScopeResource(scope);
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
const isLoginError = obj.stderr.match("(.*)az login(.*)");
|
|
1545
|
-
const isNotInstallError = obj.stderr.match("az:(.*)not found") || obj.stderr.startsWith("'az' is not recognized");
|
|
1550
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
1551
|
+
var _a, _b, _c, _d;
|
|
1552
|
+
try {
|
|
1553
|
+
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId);
|
|
1554
|
+
const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
|
|
1555
|
+
const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
|
|
1556
|
+
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"));
|
|
1546
1557
|
if (isNotInstallError) {
|
|
1547
|
-
const error = new CredentialUnavailableError("Azure CLI could not be found.
|
|
1548
|
-
logger$
|
|
1558
|
+
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'.");
|
|
1559
|
+
logger$i.getToken.info(formatError(scopes, error));
|
|
1549
1560
|
throw error;
|
|
1550
1561
|
}
|
|
1551
|
-
|
|
1562
|
+
if (isLoginError) {
|
|
1552
1563
|
const error = new CredentialUnavailableError("Please run 'az login' from a command prompt to authenticate before using this credential.");
|
|
1553
|
-
logger$
|
|
1564
|
+
logger$i.getToken.info(formatError(scopes, error));
|
|
1554
1565
|
throw error;
|
|
1555
1566
|
}
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1567
|
+
try {
|
|
1568
|
+
const responseData = obj.stdout;
|
|
1569
|
+
const response = JSON.parse(responseData);
|
|
1570
|
+
logger$i.getToken.info(formatSuccess(scopes));
|
|
1571
|
+
const returnValue = {
|
|
1572
|
+
token: response.accessToken,
|
|
1573
|
+
expiresOnTimestamp: new Date(response.expiresOn).getTime(),
|
|
1574
|
+
};
|
|
1575
|
+
return returnValue;
|
|
1576
|
+
}
|
|
1577
|
+
catch (e) {
|
|
1578
|
+
if (obj.stderr) {
|
|
1579
|
+
throw new CredentialUnavailableError(obj.stderr);
|
|
1580
|
+
}
|
|
1581
|
+
throw e;
|
|
1582
|
+
}
|
|
1559
1583
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
expiresOnTimestamp: new Date(response.expiresOn).getTime(),
|
|
1567
|
-
};
|
|
1568
|
-
return returnValue;
|
|
1584
|
+
catch (err) {
|
|
1585
|
+
const error = err.name === "CredentialUnavailableError"
|
|
1586
|
+
? err
|
|
1587
|
+
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
|
|
1588
|
+
logger$i.getToken.info(formatError(scopes, error));
|
|
1589
|
+
throw error;
|
|
1569
1590
|
}
|
|
1570
|
-
}
|
|
1571
|
-
catch (err) {
|
|
1572
|
-
const error = new Error(err.message || "Unknown error while trying to retrieve the access token");
|
|
1573
|
-
span.setStatus({
|
|
1574
|
-
code: coreTracing.SpanStatusCode.ERROR,
|
|
1575
|
-
message: error.message,
|
|
1576
|
-
});
|
|
1577
|
-
logger$g.getToken.info(formatError(scopes, error));
|
|
1578
|
-
throw error;
|
|
1579
|
-
}
|
|
1591
|
+
});
|
|
1580
1592
|
}
|
|
1581
1593
|
}
|
|
1582
1594
|
|
|
@@ -1611,7 +1623,7 @@ const processUtils = {
|
|
|
1611
1623
|
};
|
|
1612
1624
|
|
|
1613
1625
|
// Copyright (c) Microsoft Corporation.
|
|
1614
|
-
const logger$
|
|
1626
|
+
const logger$h = credentialLogger("AzurePowerShellCredential");
|
|
1615
1627
|
const isWindows = process.platform === "win32";
|
|
1616
1628
|
/**
|
|
1617
1629
|
* Returns a platform-appropriate command name by appending ".exe" on Windows.
|
|
@@ -1739,18 +1751,18 @@ class AzurePowerShellCredential {
|
|
|
1739
1751
|
* @param options - The options used to configure any requests this TokenCredential implementation might make.
|
|
1740
1752
|
*/
|
|
1741
1753
|
async getToken(scopes, options = {}) {
|
|
1742
|
-
return
|
|
1754
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
1743
1755
|
const tenantId = processMultiTenantRequest(this.tenantId, options);
|
|
1744
1756
|
if (tenantId) {
|
|
1745
|
-
checkTenantId(logger$
|
|
1757
|
+
checkTenantId(logger$h, tenantId);
|
|
1746
1758
|
}
|
|
1747
1759
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
1748
|
-
ensureValidScope(scope, logger$
|
|
1749
|
-
logger$
|
|
1760
|
+
ensureValidScope(scope, logger$h);
|
|
1761
|
+
logger$h.getToken.info(`Using the scope ${scope}`);
|
|
1750
1762
|
const resource = getScopeResource(scope);
|
|
1751
1763
|
try {
|
|
1752
1764
|
const response = await this.getAzurePowerShellAccessToken(resource, tenantId);
|
|
1753
|
-
logger$
|
|
1765
|
+
logger$h.getToken.info(formatSuccess(scopes));
|
|
1754
1766
|
return {
|
|
1755
1767
|
token: response.Token,
|
|
1756
1768
|
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
|
|
@@ -1759,16 +1771,16 @@ class AzurePowerShellCredential {
|
|
|
1759
1771
|
catch (err) {
|
|
1760
1772
|
if (isNotInstalledError(err)) {
|
|
1761
1773
|
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
|
|
1762
|
-
logger$
|
|
1774
|
+
logger$h.getToken.info(formatError(scope, error));
|
|
1763
1775
|
throw error;
|
|
1764
1776
|
}
|
|
1765
1777
|
else if (isLoginError(err)) {
|
|
1766
1778
|
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
|
|
1767
|
-
logger$
|
|
1779
|
+
logger$h.getToken.info(formatError(scope, error));
|
|
1768
1780
|
throw error;
|
|
1769
1781
|
}
|
|
1770
1782
|
const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
|
|
1771
|
-
logger$
|
|
1783
|
+
logger$h.getToken.info(formatError(scope, error));
|
|
1772
1784
|
throw error;
|
|
1773
1785
|
}
|
|
1774
1786
|
});
|
|
@@ -1806,7 +1818,7 @@ class MsalClientSecret extends MsalNode {
|
|
|
1806
1818
|
}
|
|
1807
1819
|
|
|
1808
1820
|
// Copyright (c) Microsoft Corporation.
|
|
1809
|
-
const logger$
|
|
1821
|
+
const logger$g = credentialLogger("ClientSecretCredential");
|
|
1810
1822
|
/**
|
|
1811
1823
|
* Enables authentication to Azure Active Directory using a client secret
|
|
1812
1824
|
* that was generated for an App Registration. More information on how
|
|
@@ -1830,7 +1842,7 @@ class ClientSecretCredential {
|
|
|
1830
1842
|
if (!tenantId || !clientId || !clientSecret) {
|
|
1831
1843
|
throw new Error("ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.");
|
|
1832
1844
|
}
|
|
1833
|
-
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$
|
|
1845
|
+
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$g,
|
|
1834
1846
|
clientId,
|
|
1835
1847
|
tenantId,
|
|
1836
1848
|
clientSecret, tokenCredentialOptions: options }));
|
|
@@ -1844,7 +1856,7 @@ class ClientSecretCredential {
|
|
|
1844
1856
|
* TokenCredential implementation might make.
|
|
1845
1857
|
*/
|
|
1846
1858
|
async getToken(scopes, options = {}) {
|
|
1847
|
-
return
|
|
1859
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
1848
1860
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
1849
1861
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
1850
1862
|
});
|
|
@@ -1863,8 +1875,12 @@ const readFileAsync$2 = util.promisify(fs.readFile);
|
|
|
1863
1875
|
*/
|
|
1864
1876
|
async function parseCertificate(configuration, sendCertificateChain) {
|
|
1865
1877
|
const certificateParts = {};
|
|
1878
|
+
const certificate = configuration
|
|
1879
|
+
.certificate;
|
|
1880
|
+
const certificatePath = configuration
|
|
1881
|
+
.certificatePath;
|
|
1866
1882
|
certificateParts.certificateContents =
|
|
1867
|
-
|
|
1883
|
+
certificate || (await readFileAsync$2(certificatePath, "utf8"));
|
|
1868
1884
|
if (sendCertificateChain) {
|
|
1869
1885
|
certificateParts.x5c = certificateParts.certificateContents;
|
|
1870
1886
|
}
|
|
@@ -1916,13 +1932,14 @@ class MsalClientCertificate extends MsalNode {
|
|
|
1916
1932
|
}
|
|
1917
1933
|
async doGetToken(scopes, options = {}) {
|
|
1918
1934
|
try {
|
|
1919
|
-
const
|
|
1935
|
+
const clientCredReq = {
|
|
1920
1936
|
scopes,
|
|
1921
1937
|
correlationId: options.correlationId,
|
|
1922
1938
|
azureRegion: this.azureRegion,
|
|
1923
1939
|
authority: options.authority,
|
|
1924
1940
|
claims: options.claims,
|
|
1925
|
-
}
|
|
1941
|
+
};
|
|
1942
|
+
const result = await this.confidentialApp.acquireTokenByClientCredential(clientCredReq);
|
|
1926
1943
|
// Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,
|
|
1927
1944
|
// The Client Credential flow does not return the account information from the authentication service,
|
|
1928
1945
|
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
@@ -1936,7 +1953,7 @@ class MsalClientCertificate extends MsalNode {
|
|
|
1936
1953
|
|
|
1937
1954
|
// Copyright (c) Microsoft Corporation.
|
|
1938
1955
|
const credentialName$2 = "ClientCertificateCredential";
|
|
1939
|
-
const logger$
|
|
1956
|
+
const logger$f = credentialLogger(credentialName$2);
|
|
1940
1957
|
/**
|
|
1941
1958
|
* Enables authentication to Azure Active Directory using a PEM-encoded
|
|
1942
1959
|
* certificate that is assigned to an App Registration. More information
|
|
@@ -1955,14 +1972,17 @@ class ClientCertificateCredential {
|
|
|
1955
1972
|
certificatePath: certificatePathOrConfiguration,
|
|
1956
1973
|
}
|
|
1957
1974
|
: certificatePathOrConfiguration));
|
|
1958
|
-
|
|
1975
|
+
const certificate = configuration
|
|
1976
|
+
.certificate;
|
|
1977
|
+
const certificatePath = configuration.certificatePath;
|
|
1978
|
+
if (!configuration || !(certificate || certificatePath)) {
|
|
1959
1979
|
throw new Error(`${credentialName$2}: Provide either a PEM certificate in string form, or the path to that certificate in the filesystem. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
|
|
1960
1980
|
}
|
|
1961
|
-
if (
|
|
1981
|
+
if (certificate && certificatePath) {
|
|
1962
1982
|
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.`);
|
|
1963
1983
|
}
|
|
1964
1984
|
this.msalFlow = new MsalClientCertificate(Object.assign(Object.assign({}, options), { configuration,
|
|
1965
|
-
logger: logger$
|
|
1985
|
+
logger: logger$f,
|
|
1966
1986
|
clientId,
|
|
1967
1987
|
tenantId, sendCertificateChain: options.sendCertificateChain, tokenCredentialOptions: options }));
|
|
1968
1988
|
}
|
|
@@ -1975,7 +1995,7 @@ class ClientCertificateCredential {
|
|
|
1975
1995
|
* TokenCredential implementation might make.
|
|
1976
1996
|
*/
|
|
1977
1997
|
async getToken(scopes, options = {}) {
|
|
1978
|
-
return
|
|
1998
|
+
return tracingClient.withSpan(`${credentialName$2}.getToken`, options, async (newOptions) => {
|
|
1979
1999
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
1980
2000
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
1981
2001
|
});
|
|
@@ -2013,7 +2033,7 @@ class MsalUsernamePassword extends MsalNode {
|
|
|
2013
2033
|
}
|
|
2014
2034
|
|
|
2015
2035
|
// Copyright (c) Microsoft Corporation.
|
|
2016
|
-
const logger$
|
|
2036
|
+
const logger$e = credentialLogger("UsernamePasswordCredential");
|
|
2017
2037
|
/**
|
|
2018
2038
|
* Enables authentication to Azure Active Directory with a user's
|
|
2019
2039
|
* username and password. This credential requires a high degree of
|
|
@@ -2036,7 +2056,7 @@ class UsernamePasswordCredential {
|
|
|
2036
2056
|
if (!tenantId || !clientId || !username || !password) {
|
|
2037
2057
|
throw new Error("UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.");
|
|
2038
2058
|
}
|
|
2039
|
-
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$
|
|
2059
|
+
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$e,
|
|
2040
2060
|
clientId,
|
|
2041
2061
|
tenantId,
|
|
2042
2062
|
username,
|
|
@@ -2055,7 +2075,7 @@ class UsernamePasswordCredential {
|
|
|
2055
2075
|
* TokenCredential implementation might make.
|
|
2056
2076
|
*/
|
|
2057
2077
|
async getToken(scopes, options = {}) {
|
|
2058
|
-
return
|
|
2078
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
2059
2079
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
2060
2080
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
2061
2081
|
});
|
|
@@ -2079,7 +2099,7 @@ const AllSupportedEnvironmentVariables = [
|
|
|
2079
2099
|
"AZURE_PASSWORD",
|
|
2080
2100
|
];
|
|
2081
2101
|
const credentialName$1 = "EnvironmentCredential";
|
|
2082
|
-
const logger$
|
|
2102
|
+
const logger$d = credentialLogger(credentialName$1);
|
|
2083
2103
|
/**
|
|
2084
2104
|
* Enables authentication to Azure Active Directory using client secret
|
|
2085
2105
|
* details configured in environment variables
|
|
@@ -2109,26 +2129,26 @@ class EnvironmentCredential {
|
|
|
2109
2129
|
// Keep track of any missing environment variables for error details
|
|
2110
2130
|
this._credential = undefined;
|
|
2111
2131
|
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
|
|
2112
|
-
logger$
|
|
2132
|
+
logger$d.info(`Found the following environment variables: ${assigned}`);
|
|
2113
2133
|
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
2114
2134
|
if (tenantId) {
|
|
2115
|
-
checkTenantId(logger$
|
|
2135
|
+
checkTenantId(logger$d, tenantId);
|
|
2116
2136
|
}
|
|
2117
2137
|
if (tenantId && clientId && clientSecret) {
|
|
2118
|
-
logger$
|
|
2138
|
+
logger$d.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
|
|
2119
2139
|
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
|
|
2120
2140
|
return;
|
|
2121
2141
|
}
|
|
2122
2142
|
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
|
|
2123
2143
|
if (tenantId && clientId && certificatePath) {
|
|
2124
|
-
logger$
|
|
2144
|
+
logger$d.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
|
|
2125
2145
|
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath }, options);
|
|
2126
2146
|
return;
|
|
2127
2147
|
}
|
|
2128
2148
|
const username = process.env.AZURE_USERNAME;
|
|
2129
2149
|
const password = process.env.AZURE_PASSWORD;
|
|
2130
2150
|
if (tenantId && clientId && username && password) {
|
|
2131
|
-
logger$
|
|
2151
|
+
logger$d.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
|
|
2132
2152
|
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, options);
|
|
2133
2153
|
}
|
|
2134
2154
|
}
|
|
@@ -2139,11 +2159,11 @@ class EnvironmentCredential {
|
|
|
2139
2159
|
* @param options - Optional parameters. See {@link GetTokenOptions}.
|
|
2140
2160
|
*/
|
|
2141
2161
|
async getToken(scopes, options = {}) {
|
|
2142
|
-
return
|
|
2162
|
+
return tracingClient.withSpan(`${credentialName$1}.getToken`, options, async (newOptions) => {
|
|
2143
2163
|
if (this._credential) {
|
|
2144
2164
|
try {
|
|
2145
2165
|
const result = await this._credential.getToken(scopes, newOptions);
|
|
2146
|
-
logger$
|
|
2166
|
+
logger$d.getToken.info(formatSuccess(scopes));
|
|
2147
2167
|
return result;
|
|
2148
2168
|
}
|
|
2149
2169
|
catch (err) {
|
|
@@ -2151,7 +2171,7 @@ class EnvironmentCredential {
|
|
|
2151
2171
|
error: `${credentialName$1} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
|
|
2152
2172
|
error_description: err.message.toString().split("More details:").join(""),
|
|
2153
2173
|
});
|
|
2154
|
-
logger$
|
|
2174
|
+
logger$d.getToken.info(formatError(scopes, authenticationError));
|
|
2155
2175
|
throw authenticationError;
|
|
2156
2176
|
}
|
|
2157
2177
|
}
|
|
@@ -2197,22 +2217,22 @@ function mapScopesToResource(scopes) {
|
|
|
2197
2217
|
}
|
|
2198
2218
|
|
|
2199
2219
|
// Copyright (c) Microsoft Corporation.
|
|
2200
|
-
const msiName$
|
|
2201
|
-
const logger$
|
|
2220
|
+
const msiName$6 = "ManagedIdentityCredential - AppServiceMSI 2017";
|
|
2221
|
+
const logger$c = credentialLogger(msiName$6);
|
|
2202
2222
|
/**
|
|
2203
2223
|
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2204
2224
|
*/
|
|
2205
|
-
function expiresOnParser$
|
|
2225
|
+
function expiresOnParser$3(requestBody) {
|
|
2206
2226
|
// App Service always returns string expires_on values.
|
|
2207
2227
|
return Date.parse(requestBody.expires_on);
|
|
2208
2228
|
}
|
|
2209
2229
|
/**
|
|
2210
2230
|
* Generates the options used on the request for an access token.
|
|
2211
2231
|
*/
|
|
2212
|
-
function prepareRequestOptions$
|
|
2232
|
+
function prepareRequestOptions$6(scopes, clientId) {
|
|
2213
2233
|
const resource = mapScopesToResource(scopes);
|
|
2214
2234
|
if (!resource) {
|
|
2215
|
-
throw new Error(`${msiName$
|
|
2235
|
+
throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
|
|
2216
2236
|
}
|
|
2217
2237
|
const queryParameters = {
|
|
2218
2238
|
resource,
|
|
@@ -2224,10 +2244,10 @@ function prepareRequestOptions$5(scopes, clientId) {
|
|
|
2224
2244
|
const query = new URLSearchParams(queryParameters);
|
|
2225
2245
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2226
2246
|
if (!process.env.MSI_ENDPOINT) {
|
|
2227
|
-
throw new Error(`${msiName$
|
|
2247
|
+
throw new Error(`${msiName$6}: Missing environment variable: MSI_ENDPOINT`);
|
|
2228
2248
|
}
|
|
2229
2249
|
if (!process.env.MSI_SECRET) {
|
|
2230
|
-
throw new Error(`${msiName$
|
|
2250
|
+
throw new Error(`${msiName$6}: Missing environment variable: MSI_SECRET`);
|
|
2231
2251
|
}
|
|
2232
2252
|
return {
|
|
2233
2253
|
url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
|
|
@@ -2245,40 +2265,40 @@ const appServiceMsi2017 = {
|
|
|
2245
2265
|
async isAvailable({ scopes }) {
|
|
2246
2266
|
const resource = mapScopesToResource(scopes);
|
|
2247
2267
|
if (!resource) {
|
|
2248
|
-
logger$
|
|
2268
|
+
logger$c.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
|
|
2249
2269
|
return false;
|
|
2250
2270
|
}
|
|
2251
2271
|
const env = process.env;
|
|
2252
2272
|
const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
|
|
2253
2273
|
if (!result) {
|
|
2254
|
-
logger$
|
|
2274
|
+
logger$c.info(`${msiName$6}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
|
|
2255
2275
|
}
|
|
2256
2276
|
return result;
|
|
2257
2277
|
},
|
|
2258
2278
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2259
2279
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2260
2280
|
if (resourceId) {
|
|
2261
|
-
logger$
|
|
2281
|
+
logger$c.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2262
2282
|
}
|
|
2263
|
-
logger$
|
|
2264
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
2283
|
+
logger$c.info(`${msiName$6}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
2284
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$6(scopes, clientId)), {
|
|
2265
2285
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2266
2286
|
allowInsecureConnection: true }));
|
|
2267
|
-
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$
|
|
2287
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$3);
|
|
2268
2288
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2269
2289
|
},
|
|
2270
2290
|
};
|
|
2271
2291
|
|
|
2272
2292
|
// Copyright (c) Microsoft Corporation.
|
|
2273
|
-
const msiName$
|
|
2274
|
-
const logger$
|
|
2293
|
+
const msiName$5 = "ManagedIdentityCredential - CloudShellMSI";
|
|
2294
|
+
const logger$b = credentialLogger(msiName$5);
|
|
2275
2295
|
/**
|
|
2276
2296
|
* Generates the options used on the request for an access token.
|
|
2277
2297
|
*/
|
|
2278
|
-
function prepareRequestOptions$
|
|
2298
|
+
function prepareRequestOptions$5(scopes, clientId, resourceId) {
|
|
2279
2299
|
const resource = mapScopesToResource(scopes);
|
|
2280
2300
|
if (!resource) {
|
|
2281
|
-
throw new Error(`${msiName$
|
|
2301
|
+
throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
|
|
2282
2302
|
}
|
|
2283
2303
|
const body = {
|
|
2284
2304
|
resource,
|
|
@@ -2291,7 +2311,7 @@ function prepareRequestOptions$4(scopes, clientId, resourceId) {
|
|
|
2291
2311
|
}
|
|
2292
2312
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2293
2313
|
if (!process.env.MSI_ENDPOINT) {
|
|
2294
|
-
throw new Error(`${msiName$
|
|
2314
|
+
throw new Error(`${msiName$5}: Missing environment variable: MSI_ENDPOINT`);
|
|
2295
2315
|
}
|
|
2296
2316
|
const params = new URLSearchParams(body);
|
|
2297
2317
|
return {
|
|
@@ -2313,25 +2333,25 @@ const cloudShellMsi = {
|
|
|
2313
2333
|
async isAvailable({ scopes }) {
|
|
2314
2334
|
const resource = mapScopesToResource(scopes);
|
|
2315
2335
|
if (!resource) {
|
|
2316
|
-
logger$
|
|
2336
|
+
logger$b.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
|
|
2317
2337
|
return false;
|
|
2318
2338
|
}
|
|
2319
2339
|
const result = Boolean(process.env.MSI_ENDPOINT);
|
|
2320
2340
|
if (!result) {
|
|
2321
|
-
logger$
|
|
2341
|
+
logger$b.info(`${msiName$5}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
|
|
2322
2342
|
}
|
|
2323
2343
|
return result;
|
|
2324
2344
|
},
|
|
2325
2345
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2326
2346
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2327
2347
|
if (clientId) {
|
|
2328
|
-
logger$
|
|
2348
|
+
logger$b.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
2329
2349
|
}
|
|
2330
2350
|
if (resourceId) {
|
|
2331
|
-
logger$
|
|
2351
|
+
logger$b.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
|
2332
2352
|
}
|
|
2333
|
-
logger$
|
|
2334
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
2353
|
+
logger$b.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
2354
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId, resourceId)), {
|
|
2335
2355
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2336
2356
|
allowInsecureConnection: true }));
|
|
2337
2357
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -2340,33 +2360,33 @@ const cloudShellMsi = {
|
|
|
2340
2360
|
};
|
|
2341
2361
|
|
|
2342
2362
|
// Copyright (c) Microsoft Corporation.
|
|
2343
|
-
const msiName$
|
|
2344
|
-
const logger$
|
|
2363
|
+
const msiName$4 = "ManagedIdentityCredential - IMDS";
|
|
2364
|
+
const logger$a = credentialLogger(msiName$4);
|
|
2345
2365
|
/**
|
|
2346
2366
|
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2347
2367
|
*/
|
|
2348
|
-
function expiresOnParser$
|
|
2368
|
+
function expiresOnParser$2(requestBody) {
|
|
2349
2369
|
if (requestBody.expires_on) {
|
|
2350
2370
|
// Use the expires_on timestamp if it's available
|
|
2351
2371
|
const expires = +requestBody.expires_on * 1000;
|
|
2352
|
-
logger$
|
|
2372
|
+
logger$a.info(`${msiName$4}: Using expires_on: ${expires} (original value: ${requestBody.expires_on})`);
|
|
2353
2373
|
return expires;
|
|
2354
2374
|
}
|
|
2355
2375
|
else {
|
|
2356
2376
|
// If these aren't possible, use expires_in and calculate a timestamp
|
|
2357
2377
|
const expires = Date.now() + requestBody.expires_in * 1000;
|
|
2358
|
-
logger$
|
|
2378
|
+
logger$a.info(`${msiName$4}: IMDS using expires_in: ${expires} (original value: ${requestBody.expires_in})`);
|
|
2359
2379
|
return expires;
|
|
2360
2380
|
}
|
|
2361
2381
|
}
|
|
2362
2382
|
/**
|
|
2363
2383
|
* Generates the options used on the request for an access token.
|
|
2364
2384
|
*/
|
|
2365
|
-
function prepareRequestOptions$
|
|
2385
|
+
function prepareRequestOptions$4(scopes, clientId, resourceId, options) {
|
|
2366
2386
|
var _a;
|
|
2367
2387
|
const resource = mapScopesToResource(scopes);
|
|
2368
2388
|
if (!resource) {
|
|
2369
|
-
throw new Error(`${msiName$
|
|
2389
|
+
throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
|
|
2370
2390
|
}
|
|
2371
2391
|
const { skipQuery, skipMetadataHeader } = options || {};
|
|
2372
2392
|
let query = "";
|
|
@@ -2412,14 +2432,12 @@ const imdsMsiRetryConfig = {
|
|
|
2412
2432
|
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
2413
2433
|
*/
|
|
2414
2434
|
const imdsMsi = {
|
|
2415
|
-
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions, }) {
|
|
2416
|
-
var _a, _b;
|
|
2435
|
+
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
|
|
2417
2436
|
const resource = mapScopesToResource(scopes);
|
|
2418
2437
|
if (!resource) {
|
|
2419
|
-
logger$
|
|
2438
|
+
logger$a.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
|
|
2420
2439
|
return false;
|
|
2421
2440
|
}
|
|
2422
|
-
const { span, updatedOptions: options } = createSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions);
|
|
2423
2441
|
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
|
|
2424
2442
|
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
2425
2443
|
return true;
|
|
@@ -2427,66 +2445,58 @@ const imdsMsi = {
|
|
|
2427
2445
|
if (!identityClient) {
|
|
2428
2446
|
throw new Error("Missing IdentityClient");
|
|
2429
2447
|
}
|
|
2430
|
-
const requestOptions = prepareRequestOptions$
|
|
2448
|
+
const requestOptions = prepareRequestOptions$4(resource, clientId, resourceId, {
|
|
2431
2449
|
skipMetadataHeader: true,
|
|
2432
2450
|
skipQuery: true,
|
|
2433
2451
|
});
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
// not having a "Metadata" header should cause an error to be
|
|
2438
|
-
// returned quickly from the endpoint, proving its availability.
|
|
2439
|
-
const request = coreRestPipeline.createPipelineRequest(requestOptions);
|
|
2440
|
-
request.timeout = (_b = (_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) !== null && _b !== void 0 ? _b : 300;
|
|
2441
|
-
// This MSI uses the imdsEndpoint to get the token, which only uses http://
|
|
2442
|
-
request.allowInsecureConnection = true;
|
|
2452
|
+
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
|
|
2453
|
+
var _a, _b;
|
|
2454
|
+
requestOptions.tracingOptions = options.tracingOptions;
|
|
2443
2455
|
try {
|
|
2444
|
-
|
|
2445
|
-
|
|
2456
|
+
// Create a request with a timeout since we expect that
|
|
2457
|
+
// not having a "Metadata" header should cause an error to be
|
|
2458
|
+
// returned quickly from the endpoint, proving its availability.
|
|
2459
|
+
const request = coreRestPipeline.createPipelineRequest(requestOptions);
|
|
2460
|
+
request.timeout = (_b = (_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) !== null && _b !== void 0 ? _b : 300;
|
|
2461
|
+
// This MSI uses the imdsEndpoint to get the token, which only uses http://
|
|
2462
|
+
request.allowInsecureConnection = true;
|
|
2463
|
+
try {
|
|
2464
|
+
logger$a.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
|
|
2465
|
+
await identityClient.sendRequest(request);
|
|
2466
|
+
}
|
|
2467
|
+
catch (err) {
|
|
2468
|
+
if ((err.name === "RestError" && err.code === coreRestPipeline.RestError.REQUEST_SEND_ERROR) ||
|
|
2469
|
+
err.name === "AbortError" ||
|
|
2470
|
+
err.code === "ENETUNREACH" || // Network unreachable
|
|
2471
|
+
err.code === "ECONNREFUSED" || // connection refused
|
|
2472
|
+
err.code === "EHOSTDOWN" // host is down
|
|
2473
|
+
) {
|
|
2474
|
+
// If the request failed, or Node.js was unable to establish a connection,
|
|
2475
|
+
// or the host was down, we'll assume the IMDS endpoint isn't available.
|
|
2476
|
+
logger$a.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
|
|
2477
|
+
return false;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
// If we received any response, the endpoint is available
|
|
2481
|
+
logger$a.info(`${msiName$4}: The Azure IMDS endpoint is available`);
|
|
2482
|
+
return true;
|
|
2446
2483
|
}
|
|
2447
2484
|
catch (err) {
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
err.code === "EHOSTDOWN" // host is down
|
|
2453
|
-
) {
|
|
2454
|
-
// If the request failed, or Node.js was unable to establish a connection,
|
|
2455
|
-
// or the host was down, we'll assume the IMDS endpoint isn't available.
|
|
2456
|
-
logger$8.info(`${msiName$3}: The Azure IMDS endpoint is unavailable`);
|
|
2457
|
-
span.setStatus({
|
|
2458
|
-
code: coreTracing.SpanStatusCode.ERROR,
|
|
2459
|
-
message: err.message,
|
|
2460
|
-
});
|
|
2461
|
-
return false;
|
|
2462
|
-
}
|
|
2485
|
+
// createWebResource failed.
|
|
2486
|
+
// This error should bubble up to the user.
|
|
2487
|
+
logger$a.info(`${msiName$4}: Error when creating the WebResource for the Azure IMDS endpoint: ${err.message}`);
|
|
2488
|
+
throw err;
|
|
2463
2489
|
}
|
|
2464
|
-
|
|
2465
|
-
logger$8.info(`${msiName$3}: The Azure IMDS endpoint is available`);
|
|
2466
|
-
return true;
|
|
2467
|
-
}
|
|
2468
|
-
catch (err) {
|
|
2469
|
-
// createWebResource failed.
|
|
2470
|
-
// This error should bubble up to the user.
|
|
2471
|
-
logger$8.info(`${msiName$3}: Error when creating the WebResource for the Azure IMDS endpoint: ${err.message}`);
|
|
2472
|
-
span.setStatus({
|
|
2473
|
-
code: coreTracing.SpanStatusCode.ERROR,
|
|
2474
|
-
message: err.message,
|
|
2475
|
-
});
|
|
2476
|
-
throw err;
|
|
2477
|
-
}
|
|
2478
|
-
finally {
|
|
2479
|
-
span.end();
|
|
2480
|
-
}
|
|
2490
|
+
});
|
|
2481
2491
|
},
|
|
2482
2492
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2483
2493
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2484
|
-
logger$
|
|
2494
|
+
logger$a.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
|
|
2485
2495
|
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
|
|
2486
2496
|
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
|
|
2487
2497
|
try {
|
|
2488
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
2489
|
-
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$
|
|
2498
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
|
|
2499
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$2);
|
|
2490
2500
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2491
2501
|
}
|
|
2492
2502
|
catch (error) {
|
|
@@ -2498,20 +2508,20 @@ const imdsMsi = {
|
|
|
2498
2508
|
throw error;
|
|
2499
2509
|
}
|
|
2500
2510
|
}
|
|
2501
|
-
throw new AuthenticationError(404, `${msiName$
|
|
2511
|
+
throw new AuthenticationError(404, `${msiName$4}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
|
|
2502
2512
|
},
|
|
2503
2513
|
};
|
|
2504
2514
|
|
|
2505
2515
|
// Copyright (c) Microsoft Corporation.
|
|
2506
|
-
const msiName$
|
|
2507
|
-
const logger$
|
|
2516
|
+
const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
|
|
2517
|
+
const logger$9 = credentialLogger(msiName$3);
|
|
2508
2518
|
/**
|
|
2509
2519
|
* Generates the options used on the request for an access token.
|
|
2510
2520
|
*/
|
|
2511
|
-
function prepareRequestOptions$
|
|
2521
|
+
function prepareRequestOptions$3(scopes, clientId, resourceId) {
|
|
2512
2522
|
const resource = mapScopesToResource(scopes);
|
|
2513
2523
|
if (!resource) {
|
|
2514
|
-
throw new Error(`${msiName$
|
|
2524
|
+
throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
|
|
2515
2525
|
}
|
|
2516
2526
|
const queryParameters = {
|
|
2517
2527
|
resource,
|
|
@@ -2525,7 +2535,7 @@ function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
|
2525
2535
|
}
|
|
2526
2536
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2527
2537
|
if (!process.env.IDENTITY_ENDPOINT) {
|
|
2528
|
-
throw new Error(`${msiName$
|
|
2538
|
+
throw new Error(`${msiName$3}: Missing environment variable: IDENTITY_ENDPOINT`);
|
|
2529
2539
|
}
|
|
2530
2540
|
const query = new URLSearchParams(queryParameters);
|
|
2531
2541
|
return coreRestPipeline.createPipelineRequest({
|
|
@@ -2560,7 +2570,7 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
2560
2570
|
if (response.bodyAsText) {
|
|
2561
2571
|
message = ` Response: ${response.bodyAsText}`;
|
|
2562
2572
|
}
|
|
2563
|
-
throw new AuthenticationError(response.status, `${msiName$
|
|
2573
|
+
throw new AuthenticationError(response.status, `${msiName$3}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
|
|
2564
2574
|
}
|
|
2565
2575
|
const authHeader = response.headers.get("www-authenticate") || "";
|
|
2566
2576
|
try {
|
|
@@ -2577,12 +2587,12 @@ const arcMsi = {
|
|
|
2577
2587
|
async isAvailable({ scopes }) {
|
|
2578
2588
|
const resource = mapScopesToResource(scopes);
|
|
2579
2589
|
if (!resource) {
|
|
2580
|
-
logger$
|
|
2590
|
+
logger$9.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
|
|
2581
2591
|
return false;
|
|
2582
2592
|
}
|
|
2583
2593
|
const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
|
|
2584
2594
|
if (!result) {
|
|
2585
|
-
logger$
|
|
2595
|
+
logger$9.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
|
|
2586
2596
|
}
|
|
2587
2597
|
return result;
|
|
2588
2598
|
},
|
|
@@ -2590,16 +2600,16 @@ const arcMsi = {
|
|
|
2590
2600
|
var _a;
|
|
2591
2601
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2592
2602
|
if (clientId) {
|
|
2593
|
-
logger$
|
|
2603
|
+
logger$9.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
2594
2604
|
}
|
|
2595
2605
|
if (resourceId) {
|
|
2596
|
-
logger$
|
|
2606
|
+
logger$9.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
|
|
2597
2607
|
}
|
|
2598
|
-
logger$
|
|
2599
|
-
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
2608
|
+
logger$9.info(`${msiName$3}: Authenticating.`);
|
|
2609
|
+
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
|
2600
2610
|
const filePath = await filePathRequest(identityClient, requestOptions);
|
|
2601
2611
|
if (!filePath) {
|
|
2602
|
-
throw new Error(`${msiName$
|
|
2612
|
+
throw new Error(`${msiName$3}: Failed to find the token file.`);
|
|
2603
2613
|
}
|
|
2604
2614
|
const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
|
|
2605
2615
|
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
|
@@ -2612,13 +2622,13 @@ const arcMsi = {
|
|
|
2612
2622
|
};
|
|
2613
2623
|
|
|
2614
2624
|
// Copyright (c) Microsoft Corporation.
|
|
2615
|
-
const msiName$
|
|
2616
|
-
const logger$
|
|
2625
|
+
const msiName$2 = "ManagedIdentityCredential - Token Exchange";
|
|
2626
|
+
const logger$8 = credentialLogger(msiName$2);
|
|
2617
2627
|
const readFileAsync = util.promisify(fs__default["default"].readFile);
|
|
2618
2628
|
/**
|
|
2619
2629
|
* Generates the options used on the request for an access token.
|
|
2620
2630
|
*/
|
|
2621
|
-
function prepareRequestOptions$
|
|
2631
|
+
function prepareRequestOptions$2(scopes, clientAssertion, clientId) {
|
|
2622
2632
|
var _a;
|
|
2623
2633
|
const bodyParams = {
|
|
2624
2634
|
scope: Array.isArray(scopes) ? scopes.join(" ") : scopes,
|
|
@@ -2669,21 +2679,21 @@ function tokenExchangeMsi() {
|
|
|
2669
2679
|
const env = process.env;
|
|
2670
2680
|
const result = Boolean((clientId || env.AZURE_CLIENT_ID) && env.AZURE_TENANT_ID && azureFederatedTokenFilePath);
|
|
2671
2681
|
if (!result) {
|
|
2672
|
-
logger$
|
|
2682
|
+
logger$8.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`);
|
|
2673
2683
|
}
|
|
2674
2684
|
return result;
|
|
2675
2685
|
},
|
|
2676
2686
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2677
2687
|
const { identityClient, scopes, clientId } = configuration;
|
|
2678
|
-
logger$
|
|
2688
|
+
logger$8.info(`${msiName$2}: Using the client assertion coming from environment variables.`);
|
|
2679
2689
|
let assertion;
|
|
2680
2690
|
try {
|
|
2681
2691
|
assertion = await readAssertion();
|
|
2682
2692
|
}
|
|
2683
2693
|
catch (err) {
|
|
2684
|
-
throw new Error(`${msiName$
|
|
2694
|
+
throw new Error(`${msiName$2}: Failed to read ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
|
|
2685
2695
|
}
|
|
2686
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
2696
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID)), {
|
|
2687
2697
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2688
2698
|
allowInsecureConnection: true }));
|
|
2689
2699
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -2703,22 +2713,22 @@ function tokenExchangeMsi() {
|
|
|
2703
2713
|
//
|
|
2704
2714
|
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
2705
2715
|
//
|
|
2706
|
-
const msiName = "ManagedIdentityCredential - Fabric MSI";
|
|
2707
|
-
const logger$
|
|
2716
|
+
const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
|
|
2717
|
+
const logger$7 = credentialLogger(msiName$1);
|
|
2708
2718
|
/**
|
|
2709
2719
|
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2710
2720
|
*/
|
|
2711
|
-
function expiresOnParser(requestBody) {
|
|
2721
|
+
function expiresOnParser$1(requestBody) {
|
|
2712
2722
|
// Parses a string representation of the milliseconds since epoch into a number value
|
|
2713
2723
|
return Number(requestBody.expires_on);
|
|
2714
2724
|
}
|
|
2715
2725
|
/**
|
|
2716
2726
|
* Generates the options used on the request for an access token.
|
|
2717
2727
|
*/
|
|
2718
|
-
function prepareRequestOptions(scopes, clientId, resourceId) {
|
|
2728
|
+
function prepareRequestOptions$1(scopes, clientId, resourceId) {
|
|
2719
2729
|
const resource = mapScopesToResource(scopes);
|
|
2720
2730
|
if (!resource) {
|
|
2721
|
-
throw new Error(`${msiName}: Multiple scopes are not supported.`);
|
|
2731
|
+
throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
|
|
2722
2732
|
}
|
|
2723
2733
|
const queryParameters = {
|
|
2724
2734
|
resource,
|
|
@@ -2754,41 +2764,114 @@ const fabricMsi = {
|
|
|
2754
2764
|
async isAvailable({ scopes }) {
|
|
2755
2765
|
const resource = mapScopesToResource(scopes);
|
|
2756
2766
|
if (!resource) {
|
|
2757
|
-
logger$
|
|
2767
|
+
logger$7.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
|
|
2758
2768
|
return false;
|
|
2759
2769
|
}
|
|
2760
2770
|
const env = process.env;
|
|
2761
2771
|
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
|
|
2762
2772
|
if (!result) {
|
|
2763
|
-
logger$
|
|
2773
|
+
logger$7.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
|
|
2764
2774
|
}
|
|
2765
2775
|
return result;
|
|
2766
2776
|
},
|
|
2767
2777
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2768
2778
|
const { scopes, identityClient, clientId, resourceId } = configuration;
|
|
2769
2779
|
if (resourceId) {
|
|
2770
|
-
logger$
|
|
2780
|
+
logger$7.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2771
2781
|
}
|
|
2772
|
-
logger$
|
|
2773
|
-
`${msiName}:`,
|
|
2782
|
+
logger$7.info([
|
|
2783
|
+
`${msiName$1}:`,
|
|
2774
2784
|
"Using the endpoint and the secret coming from the environment variables:",
|
|
2775
2785
|
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
|
|
2776
2786
|
"IDENTITY_HEADER=[REDACTED] and",
|
|
2777
2787
|
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
|
|
2778
2788
|
].join(" "));
|
|
2779
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)));
|
|
2789
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
|
|
2780
2790
|
request.agent = new https__default["default"].Agent({
|
|
2781
2791
|
// This is necessary because Service Fabric provides a self-signed certificate.
|
|
2782
2792
|
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
|
2783
2793
|
rejectUnauthorized: false,
|
|
2784
2794
|
});
|
|
2795
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$1);
|
|
2796
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2797
|
+
},
|
|
2798
|
+
};
|
|
2799
|
+
|
|
2800
|
+
// Copyright (c) Microsoft Corporation.
|
|
2801
|
+
const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
|
|
2802
|
+
const logger$6 = credentialLogger(msiName);
|
|
2803
|
+
/**
|
|
2804
|
+
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2805
|
+
*/
|
|
2806
|
+
function expiresOnParser(requestBody) {
|
|
2807
|
+
// App Service always returns string expires_on values.
|
|
2808
|
+
return Date.parse(requestBody.expires_on);
|
|
2809
|
+
}
|
|
2810
|
+
/**
|
|
2811
|
+
* Generates the options used on the request for an access token.
|
|
2812
|
+
*/
|
|
2813
|
+
function prepareRequestOptions(scopes, clientId, resourceId) {
|
|
2814
|
+
const resource = mapScopesToResource(scopes);
|
|
2815
|
+
if (!resource) {
|
|
2816
|
+
throw new Error(`${msiName}: Multiple scopes are not supported.`);
|
|
2817
|
+
}
|
|
2818
|
+
const queryParameters = {
|
|
2819
|
+
resource,
|
|
2820
|
+
"api-version": "2019-08-01",
|
|
2821
|
+
};
|
|
2822
|
+
if (clientId) {
|
|
2823
|
+
queryParameters.client_id = clientId;
|
|
2824
|
+
}
|
|
2825
|
+
if (resourceId) {
|
|
2826
|
+
queryParameters.mi_res_id = resourceId;
|
|
2827
|
+
}
|
|
2828
|
+
const query = new URLSearchParams(queryParameters);
|
|
2829
|
+
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2830
|
+
if (!process.env.IDENTITY_ENDPOINT) {
|
|
2831
|
+
throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
|
|
2832
|
+
}
|
|
2833
|
+
if (!process.env.IDENTITY_HEADER) {
|
|
2834
|
+
throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
|
|
2835
|
+
}
|
|
2836
|
+
return {
|
|
2837
|
+
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
|
2838
|
+
method: "GET",
|
|
2839
|
+
headers: coreRestPipeline.createHttpHeaders({
|
|
2840
|
+
Accept: "application/json",
|
|
2841
|
+
"X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
|
|
2842
|
+
}),
|
|
2843
|
+
};
|
|
2844
|
+
}
|
|
2845
|
+
/**
|
|
2846
|
+
* 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.
|
|
2847
|
+
*/
|
|
2848
|
+
const appServiceMsi2019 = {
|
|
2849
|
+
async isAvailable({ scopes }) {
|
|
2850
|
+
const resource = mapScopesToResource(scopes);
|
|
2851
|
+
if (!resource) {
|
|
2852
|
+
logger$6.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
|
|
2853
|
+
return false;
|
|
2854
|
+
}
|
|
2855
|
+
const env = process.env;
|
|
2856
|
+
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
|
|
2857
|
+
if (!result) {
|
|
2858
|
+
logger$6.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
|
|
2859
|
+
}
|
|
2860
|
+
return result;
|
|
2861
|
+
},
|
|
2862
|
+
async getToken(configuration, getTokenOptions = {}) {
|
|
2863
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2864
|
+
logger$6.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
|
2865
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
|
|
2866
|
+
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2867
|
+
allowInsecureConnection: true }));
|
|
2785
2868
|
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
|
|
2786
2869
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2787
2870
|
},
|
|
2788
2871
|
};
|
|
2789
2872
|
|
|
2790
2873
|
// Copyright (c) Microsoft Corporation.
|
|
2791
|
-
const logger$
|
|
2874
|
+
const logger$5 = credentialLogger("ManagedIdentityCredential");
|
|
2792
2875
|
/**
|
|
2793
2876
|
* Attempts authentication using a managed identity available at the deployment environment.
|
|
2794
2877
|
* This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
|
|
@@ -2803,7 +2886,6 @@ class ManagedIdentityCredential {
|
|
|
2803
2886
|
* @hidden
|
|
2804
2887
|
*/
|
|
2805
2888
|
constructor(clientIdOrOptions, options) {
|
|
2806
|
-
var _a, _b;
|
|
2807
2889
|
this.isEndpointUnavailable = null;
|
|
2808
2890
|
let _options;
|
|
2809
2891
|
if (typeof clientIdOrOptions === "string") {
|
|
@@ -2811,10 +2893,10 @@ class ManagedIdentityCredential {
|
|
|
2811
2893
|
_options = options;
|
|
2812
2894
|
}
|
|
2813
2895
|
else {
|
|
2814
|
-
this.clientId =
|
|
2896
|
+
this.clientId = clientIdOrOptions === null || clientIdOrOptions === void 0 ? void 0 : clientIdOrOptions.clientId;
|
|
2815
2897
|
_options = clientIdOrOptions;
|
|
2816
2898
|
}
|
|
2817
|
-
this.resourceId =
|
|
2899
|
+
this.resourceId = _options === null || _options === void 0 ? void 0 : _options.resourceId;
|
|
2818
2900
|
// For JavaScript users.
|
|
2819
2901
|
if (this.clientId && this.resourceId) {
|
|
2820
2902
|
throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
|
|
@@ -2828,7 +2910,15 @@ class ManagedIdentityCredential {
|
|
|
2828
2910
|
if (this.cachedMSI) {
|
|
2829
2911
|
return this.cachedMSI;
|
|
2830
2912
|
}
|
|
2831
|
-
const MSIs = [
|
|
2913
|
+
const MSIs = [
|
|
2914
|
+
arcMsi,
|
|
2915
|
+
fabricMsi,
|
|
2916
|
+
appServiceMsi2019,
|
|
2917
|
+
appServiceMsi2017,
|
|
2918
|
+
cloudShellMsi,
|
|
2919
|
+
tokenExchangeMsi(),
|
|
2920
|
+
imdsMsi,
|
|
2921
|
+
];
|
|
2832
2922
|
for (const msi of MSIs) {
|
|
2833
2923
|
if (await msi.isAvailable({
|
|
2834
2924
|
scopes,
|
|
@@ -2844,7 +2934,7 @@ class ManagedIdentityCredential {
|
|
|
2844
2934
|
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
|
|
2845
2935
|
}
|
|
2846
2936
|
async authenticateManagedIdentity(scopes, getTokenOptions) {
|
|
2847
|
-
const { span, updatedOptions } =
|
|
2937
|
+
const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
|
|
2848
2938
|
try {
|
|
2849
2939
|
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
|
|
2850
2940
|
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
|
|
@@ -2857,8 +2947,8 @@ class ManagedIdentityCredential {
|
|
|
2857
2947
|
}
|
|
2858
2948
|
catch (err) {
|
|
2859
2949
|
span.setStatus({
|
|
2860
|
-
|
|
2861
|
-
|
|
2950
|
+
status: "error",
|
|
2951
|
+
error: err,
|
|
2862
2952
|
});
|
|
2863
2953
|
throw err;
|
|
2864
2954
|
}
|
|
@@ -2877,7 +2967,7 @@ class ManagedIdentityCredential {
|
|
|
2877
2967
|
*/
|
|
2878
2968
|
async getToken(scopes, options) {
|
|
2879
2969
|
let result = null;
|
|
2880
|
-
const { span, updatedOptions } =
|
|
2970
|
+
const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.getToken`, options);
|
|
2881
2971
|
try {
|
|
2882
2972
|
// isEndpointAvailable can be true, false, or null,
|
|
2883
2973
|
// If it's null, it means we don't yet know whether
|
|
@@ -2892,7 +2982,7 @@ class ManagedIdentityCredential {
|
|
|
2892
2982
|
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
|
|
2893
2983
|
// yet we had no access token. For this reason, we'll throw once with a specific message:
|
|
2894
2984
|
const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
|
|
2895
|
-
logger$
|
|
2985
|
+
logger$5.getToken.info(formatError(scopes, error));
|
|
2896
2986
|
throw error;
|
|
2897
2987
|
}
|
|
2898
2988
|
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
|
|
@@ -2904,10 +2994,10 @@ class ManagedIdentityCredential {
|
|
|
2904
2994
|
// We've previously determined that the endpoint was unavailable,
|
|
2905
2995
|
// either because it was unreachable or permanently unable to authenticate.
|
|
2906
2996
|
const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
|
|
2907
|
-
logger$
|
|
2997
|
+
logger$5.getToken.info(formatError(scopes, error));
|
|
2908
2998
|
throw error;
|
|
2909
2999
|
}
|
|
2910
|
-
logger$
|
|
3000
|
+
logger$5.getToken.info(formatSuccess(scopes));
|
|
2911
3001
|
return result;
|
|
2912
3002
|
}
|
|
2913
3003
|
catch (err) {
|
|
@@ -2922,21 +3012,21 @@ class ManagedIdentityCredential {
|
|
|
2922
3012
|
// if the status code was 400, it means that the endpoint is working,
|
|
2923
3013
|
// but no identity is available.
|
|
2924
3014
|
span.setStatus({
|
|
2925
|
-
|
|
2926
|
-
|
|
3015
|
+
status: "error",
|
|
3016
|
+
error: err,
|
|
2927
3017
|
});
|
|
2928
3018
|
// If either the network is unreachable,
|
|
2929
3019
|
// we can safely assume the credential is unavailable.
|
|
2930
3020
|
if (err.code === "ENETUNREACH") {
|
|
2931
3021
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
|
|
2932
|
-
logger$
|
|
3022
|
+
logger$5.getToken.info(formatError(scopes, error));
|
|
2933
3023
|
throw error;
|
|
2934
3024
|
}
|
|
2935
3025
|
// If either the host was unreachable,
|
|
2936
3026
|
// we can safely assume the credential is unavailable.
|
|
2937
3027
|
if (err.code === "EHOSTUNREACH") {
|
|
2938
3028
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
|
|
2939
|
-
logger$
|
|
3029
|
+
logger$5.getToken.info(formatError(scopes, error));
|
|
2940
3030
|
throw error;
|
|
2941
3031
|
}
|
|
2942
3032
|
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
|
@@ -2970,13 +3060,24 @@ class ManagedIdentityCredential {
|
|
|
2970
3060
|
* @internal
|
|
2971
3061
|
*/
|
|
2972
3062
|
class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
|
|
3063
|
+
// Constructor overload with just the other default options
|
|
3064
|
+
// Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
|
|
2973
3065
|
constructor(options) {
|
|
2974
|
-
var _a
|
|
2975
|
-
const managedIdentityClientId = (
|
|
2976
|
-
const managedResourceId =
|
|
3066
|
+
var _a;
|
|
3067
|
+
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
|
|
3068
|
+
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
|
|
2977
3069
|
// ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
|
|
2978
|
-
|
|
2979
|
-
|
|
3070
|
+
if (managedResourceId) {
|
|
3071
|
+
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
|
|
3072
|
+
super(managedIdentityResourceIdOptions);
|
|
3073
|
+
}
|
|
3074
|
+
else if (managedIdentityClientId) {
|
|
3075
|
+
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
|
|
3076
|
+
super(managedIdentityClientOptions);
|
|
3077
|
+
}
|
|
3078
|
+
else {
|
|
3079
|
+
super(options);
|
|
3080
|
+
}
|
|
2980
3081
|
}
|
|
2981
3082
|
}
|
|
2982
3083
|
const defaultCredentials = [
|
|
@@ -2991,30 +3092,6 @@ const defaultCredentials = [
|
|
|
2991
3092
|
* work for most applications that use the Azure SDK.
|
|
2992
3093
|
*/
|
|
2993
3094
|
class DefaultAzureCredential extends ChainedTokenCredential {
|
|
2994
|
-
/**
|
|
2995
|
-
* Creates an instance of the DefaultAzureCredential class.
|
|
2996
|
-
*
|
|
2997
|
-
* This credential provides a default {@link ChainedTokenCredential} configuration that should
|
|
2998
|
-
* work for most applications that use the Azure SDK.
|
|
2999
|
-
*
|
|
3000
|
-
* The following credential types will be tried, in order:
|
|
3001
|
-
*
|
|
3002
|
-
* - {@link EnvironmentCredential}
|
|
3003
|
-
* - {@link ManagedIdentityCredential}
|
|
3004
|
-
* - {@link VisualStudioCodeCredential}
|
|
3005
|
-
* - {@link AzureCliCredential}
|
|
3006
|
-
* - {@link AzurePowerShellCredential}
|
|
3007
|
-
*
|
|
3008
|
-
* Consult the documentation of these credential types for more information
|
|
3009
|
-
* on how they attempt authentication.
|
|
3010
|
-
*
|
|
3011
|
-
* **Note**: `VisualStudioCodeCredential` is provided by a plugin package:
|
|
3012
|
-
* `@azure/identity-vscode`. If this package is not installed and registered
|
|
3013
|
-
* using the plugin API (`useIdentityPlugin`), then authentication using
|
|
3014
|
-
* `VisualStudioCodeCredential` will not be available.
|
|
3015
|
-
*
|
|
3016
|
-
* @param options - Optional parameters. See {@link DefaultAzureCredentialOptions}.
|
|
3017
|
-
*/
|
|
3018
3095
|
constructor(options) {
|
|
3019
3096
|
super(...defaultCredentials.map((ctor) => new ctor(options)));
|
|
3020
3097
|
this.UnavailableMessage =
|
|
@@ -3022,6 +3099,86 @@ class DefaultAzureCredential extends ChainedTokenCredential {
|
|
|
3022
3099
|
}
|
|
3023
3100
|
}
|
|
3024
3101
|
|
|
3102
|
+
// Copyright (c) Microsoft Corporation.
|
|
3103
|
+
/**
|
|
3104
|
+
* MSAL client assertion client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
|
|
3105
|
+
* @internal
|
|
3106
|
+
*/
|
|
3107
|
+
class MsalClientAssertion extends MsalNode {
|
|
3108
|
+
constructor(options) {
|
|
3109
|
+
super(options);
|
|
3110
|
+
this.requiresConfidential = true;
|
|
3111
|
+
this.getAssertion = options.getAssertion;
|
|
3112
|
+
}
|
|
3113
|
+
async doGetToken(scopes, options = {}) {
|
|
3114
|
+
try {
|
|
3115
|
+
const assertion = await this.getAssertion();
|
|
3116
|
+
const result = await this.confidentialApp.acquireTokenByClientCredential({
|
|
3117
|
+
scopes,
|
|
3118
|
+
correlationId: options.correlationId,
|
|
3119
|
+
azureRegion: this.azureRegion,
|
|
3120
|
+
authority: options.authority,
|
|
3121
|
+
claims: options.claims,
|
|
3122
|
+
clientAssertion: assertion,
|
|
3123
|
+
});
|
|
3124
|
+
// The Client Credential flow does not return an account,
|
|
3125
|
+
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
3126
|
+
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
3127
|
+
}
|
|
3128
|
+
catch (err) {
|
|
3129
|
+
let err2 = err;
|
|
3130
|
+
if (err === null || err === undefined) {
|
|
3131
|
+
err2 = new Error(JSON.stringify(err));
|
|
3132
|
+
}
|
|
3133
|
+
else {
|
|
3134
|
+
err2 = coreUtil.isError(err) ? err : new Error(String(err));
|
|
3135
|
+
}
|
|
3136
|
+
throw this.handleError(scopes, err2, options);
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
// Copyright (c) Microsoft Corporation.
|
|
3142
|
+
const logger$4 = credentialLogger("ClientAssertionCredential");
|
|
3143
|
+
/**
|
|
3144
|
+
* Authenticates a service principal with a JWT assertion.
|
|
3145
|
+
*/
|
|
3146
|
+
class ClientAssertionCredential {
|
|
3147
|
+
/**
|
|
3148
|
+
* Creates an instance of the ClientAssertionCredential with the details
|
|
3149
|
+
* needed to authenticate against Azure Active Directory with a client
|
|
3150
|
+
* assertion provided by the developer through the `getAssertion` function parameter.
|
|
3151
|
+
*
|
|
3152
|
+
* @param tenantId - The Azure Active Directory tenant (directory) ID.
|
|
3153
|
+
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
3154
|
+
* @param getAssertion - A function that retrieves the assertion for the credential to use.
|
|
3155
|
+
* @param options - Options for configuring the client which makes the authentication request.
|
|
3156
|
+
*/
|
|
3157
|
+
constructor(tenantId, clientId, getAssertion, options = {}) {
|
|
3158
|
+
if (!tenantId || !clientId || !getAssertion) {
|
|
3159
|
+
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
|
|
3160
|
+
}
|
|
3161
|
+
this.tenantId = tenantId;
|
|
3162
|
+
this.clientId = clientId;
|
|
3163
|
+
this.options = options;
|
|
3164
|
+
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$4, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
|
|
3165
|
+
}
|
|
3166
|
+
/**
|
|
3167
|
+
* Authenticates with Azure Active Directory and returns an access token if successful.
|
|
3168
|
+
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3169
|
+
*
|
|
3170
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
3171
|
+
* @param options - The options used to configure any requests this
|
|
3172
|
+
* TokenCredential implementation might make.
|
|
3173
|
+
*/
|
|
3174
|
+
async getToken(scopes, options = {}) {
|
|
3175
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3176
|
+
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3177
|
+
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3178
|
+
});
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3025
3182
|
// Copyright (c) Microsoft Corporation.
|
|
3026
3183
|
/**
|
|
3027
3184
|
* A call to open(), but mockable
|
|
@@ -3173,7 +3330,8 @@ class MsalOpenBrowser extends MsalNode {
|
|
|
3173
3330
|
};
|
|
3174
3331
|
const response = await this.publicApp.getAuthCodeUrl(authCodeUrlParameters);
|
|
3175
3332
|
try {
|
|
3176
|
-
|
|
3333
|
+
// A new instance on macOS only which allows it to not hang, does not fix the issue on linux
|
|
3334
|
+
await interactiveBrowserMockable.open(response, { wait: true, newInstance: true });
|
|
3177
3335
|
}
|
|
3178
3336
|
catch (e) {
|
|
3179
3337
|
throw new CredentialUnavailableError(`InteractiveBrowserCredential: Could not open a browser window. Error: ${e.message}`);
|
|
@@ -3221,7 +3379,7 @@ class InteractiveBrowserCredential {
|
|
|
3221
3379
|
* TokenCredential implementation might make.
|
|
3222
3380
|
*/
|
|
3223
3381
|
async getToken(scopes, options = {}) {
|
|
3224
|
-
return
|
|
3382
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3225
3383
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3226
3384
|
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
|
|
3227
3385
|
});
|
|
@@ -3240,7 +3398,7 @@ class InteractiveBrowserCredential {
|
|
|
3240
3398
|
* TokenCredential implementation might make.
|
|
3241
3399
|
*/
|
|
3242
3400
|
async authenticate(scopes, options = {}) {
|
|
3243
|
-
return
|
|
3401
|
+
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
|
|
3244
3402
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3245
3403
|
await this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3246
3404
|
return this.msalFlow.getActiveAccount();
|
|
@@ -3269,8 +3427,6 @@ class MsalDeviceCode extends MsalNode {
|
|
|
3269
3427
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3270
3428
|
};
|
|
3271
3429
|
const promise = this.publicApp.acquireTokenByDeviceCode(requestOptions);
|
|
3272
|
-
// TODO:
|
|
3273
|
-
// This should work, but it currently doesn't. I'm waiting for an answer from the MSAL team.
|
|
3274
3430
|
const deviceResponse = await this.withCancellation(promise, options === null || options === void 0 ? void 0 : options.abortSignal, () => {
|
|
3275
3431
|
requestOptions.cancel = true;
|
|
3276
3432
|
});
|
|
@@ -3333,7 +3489,7 @@ class DeviceCodeCredential {
|
|
|
3333
3489
|
* TokenCredential implementation might make.
|
|
3334
3490
|
*/
|
|
3335
3491
|
async getToken(scopes, options = {}) {
|
|
3336
|
-
return
|
|
3492
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3337
3493
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3338
3494
|
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
|
|
3339
3495
|
});
|
|
@@ -3349,7 +3505,7 @@ class DeviceCodeCredential {
|
|
|
3349
3505
|
* TokenCredential implementation might make.
|
|
3350
3506
|
*/
|
|
3351
3507
|
async authenticate(scopes, options = {}) {
|
|
3352
|
-
return
|
|
3508
|
+
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
|
|
3353
3509
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3354
3510
|
await this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3355
3511
|
return this.msalFlow.getActiveAccount();
|
|
@@ -3375,12 +3531,12 @@ class MsalAuthorizationCode extends MsalNode {
|
|
|
3375
3531
|
}
|
|
3376
3532
|
async getAuthCodeUrl(options) {
|
|
3377
3533
|
await this.init();
|
|
3378
|
-
return this.confidentialApp.getAuthCodeUrl(options);
|
|
3534
|
+
return (this.confidentialApp || this.publicApp).getAuthCodeUrl(options);
|
|
3379
3535
|
}
|
|
3380
3536
|
async doGetToken(scopes, options) {
|
|
3381
3537
|
var _a;
|
|
3382
3538
|
try {
|
|
3383
|
-
const result = await ((_a = this.confidentialApp) === null || _a === void 0 ? void 0 : _a.acquireTokenByCode({
|
|
3539
|
+
const result = await ((_a = (this.confidentialApp || this.publicApp)) === null || _a === void 0 ? void 0 : _a.acquireTokenByCode({
|
|
3384
3540
|
scopes,
|
|
3385
3541
|
redirectUri: this.redirectUri,
|
|
3386
3542
|
code: this.authorizationCode,
|
|
@@ -3429,7 +3585,8 @@ class AuthorizationCodeCredential {
|
|
|
3429
3585
|
options = redirectUriOrOptions;
|
|
3430
3586
|
}
|
|
3431
3587
|
this.msalFlow = new MsalAuthorizationCode(Object.assign(Object.assign({}, options), { clientSecret,
|
|
3432
|
-
clientId,
|
|
3588
|
+
clientId,
|
|
3589
|
+
tenantId, tokenCredentialOptions: options || {}, logger: logger$1, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
|
|
3433
3590
|
}
|
|
3434
3591
|
/**
|
|
3435
3592
|
* Authenticates with Azure Active Directory and returns an access token if successful.
|
|
@@ -3440,7 +3597,7 @@ class AuthorizationCodeCredential {
|
|
|
3440
3597
|
* TokenCredential implementation might make.
|
|
3441
3598
|
*/
|
|
3442
3599
|
async getToken(scopes, options = {}) {
|
|
3443
|
-
return
|
|
3600
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3444
3601
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3445
3602
|
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
|
|
3446
3603
|
});
|
|
@@ -3507,27 +3664,6 @@ const logger = credentialLogger(credentialName);
|
|
|
3507
3664
|
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
|
|
3508
3665
|
*/
|
|
3509
3666
|
class OnBehalfOfCredential {
|
|
3510
|
-
/**
|
|
3511
|
-
* Creates an instance of the {@link OnBehalfOfCredential} with the details
|
|
3512
|
-
* needed to authenticate against Azure Active Directory with a client
|
|
3513
|
-
* secret or a path to a PEM certificate, and an user assertion.
|
|
3514
|
-
*
|
|
3515
|
-
* Example using the `KeyClient` from [\@azure/keyvault-keys](https://www.npmjs.com/package/\@azure/keyvault-keys):
|
|
3516
|
-
*
|
|
3517
|
-
* ```ts
|
|
3518
|
-
* const tokenCredential = new OnBehalfOfCredential({
|
|
3519
|
-
* tenantId,
|
|
3520
|
-
* clientId,
|
|
3521
|
-
* clientSecret, // or `certificatePath: "/path/to/certificate.pem"
|
|
3522
|
-
* userAssertionToken: "access-token"
|
|
3523
|
-
* });
|
|
3524
|
-
* const client = new KeyClient("vault-url", tokenCredential);
|
|
3525
|
-
*
|
|
3526
|
-
* await client.getKey("key-name");
|
|
3527
|
-
* ```
|
|
3528
|
-
*
|
|
3529
|
-
* @param options - Optional parameters, generally common across credentials.
|
|
3530
|
-
*/
|
|
3531
3667
|
constructor(options) {
|
|
3532
3668
|
this.options = options;
|
|
3533
3669
|
const { clientSecret } = options;
|
|
@@ -3546,7 +3682,7 @@ class OnBehalfOfCredential {
|
|
|
3546
3682
|
* @param options - The options used to configure the underlying network requests.
|
|
3547
3683
|
*/
|
|
3548
3684
|
async getToken(scopes, options = {}) {
|
|
3549
|
-
return
|
|
3685
|
+
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
|
|
3550
3686
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3551
3687
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3552
3688
|
});
|
|
@@ -3570,6 +3706,7 @@ exports.AuthorizationCodeCredential = AuthorizationCodeCredential;
|
|
|
3570
3706
|
exports.AzureCliCredential = AzureCliCredential;
|
|
3571
3707
|
exports.AzurePowerShellCredential = AzurePowerShellCredential;
|
|
3572
3708
|
exports.ChainedTokenCredential = ChainedTokenCredential;
|
|
3709
|
+
exports.ClientAssertionCredential = ClientAssertionCredential;
|
|
3573
3710
|
exports.ClientCertificateCredential = ClientCertificateCredential;
|
|
3574
3711
|
exports.ClientSecretCredential = ClientSecretCredential;
|
|
3575
3712
|
exports.CredentialUnavailableError = CredentialUnavailableError;
|
|
@@ -3584,7 +3721,7 @@ exports.UsernamePasswordCredential = UsernamePasswordCredential;
|
|
|
3584
3721
|
exports.VisualStudioCodeCredential = VisualStudioCodeCredential;
|
|
3585
3722
|
exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord;
|
|
3586
3723
|
exports.getDefaultAzureCredential = getDefaultAzureCredential;
|
|
3587
|
-
exports.logger = logger$
|
|
3724
|
+
exports.logger = logger$l;
|
|
3588
3725
|
exports.serializeAuthenticationRecord = serializeAuthenticationRecord;
|
|
3589
3726
|
exports.useIdentityPlugin = useIdentityPlugin;
|
|
3590
3727
|
//# sourceMappingURL=index.js.map
|