@azure/identity 4.3.1-alpha.20240702.3 → 4.4.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -1
- package/dist/index.js +274 -729
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +7 -0
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/constants.js +1 -1
- package/dist-esm/src/constants.js.map +1 -1
- package/dist-esm/src/credentials/azurePipelinesCredential.js +36 -21
- package/dist-esm/src/credentials/azurePipelinesCredential.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredential.js +33 -6
- package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsRetryPolicy.js +37 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsRetryPolicy.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +6 -2
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/legacyMsiProvider.js +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/legacyMsiProvider.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/msalMsiProvider.js +194 -0
- package/dist-esm/src/credentials/managedIdentityCredential/msalMsiProvider.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +19 -22
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
|
-
var logger$
|
5
|
+
var logger$m = require('@azure/logger');
|
6
6
|
var coreClient = require('@azure/core-client');
|
7
7
|
var coreUtil = require('@azure/core-util');
|
8
8
|
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
@@ -12,8 +12,6 @@ var fs = require('fs');
|
|
12
12
|
var os = require('os');
|
13
13
|
var path = require('path');
|
14
14
|
var msalCommon = require('@azure/msal-node');
|
15
|
-
var fs$1 = require('node:fs');
|
16
|
-
var https = require('https');
|
17
15
|
var open = require('open');
|
18
16
|
var promises = require('fs/promises');
|
19
17
|
var child_process = require('child_process');
|
@@ -46,7 +44,7 @@ var child_process__namespace = /*#__PURE__*/_interopNamespaceDefault(child_proce
|
|
46
44
|
/**
|
47
45
|
* Current version of the `@azure/identity` package.
|
48
46
|
*/
|
49
|
-
const SDK_VERSION = `4.
|
47
|
+
const SDK_VERSION = `4.4.1`;
|
50
48
|
/**
|
51
49
|
* The default client ID for authentication
|
52
50
|
* @internal
|
@@ -196,7 +194,7 @@ const msalPlugins = {
|
|
196
194
|
/**
|
197
195
|
* The AzureLogger used for all clients within the identity package
|
198
196
|
*/
|
199
|
-
const logger$
|
197
|
+
const logger$l = logger$m.createClientLogger("identity");
|
200
198
|
/**
|
201
199
|
* 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.
|
202
200
|
* @param supportedEnvVars - List of environment variable names
|
@@ -236,7 +234,7 @@ function formatError(scope, error) {
|
|
236
234
|
* `[title] => [message]`
|
237
235
|
*
|
238
236
|
*/
|
239
|
-
function credentialLoggerInstance(title, parent, log = logger$
|
237
|
+
function credentialLoggerInstance(title, parent, log = logger$l) {
|
240
238
|
const fullTitle = parent ? `${parent.fullTitle} ${title}` : title;
|
241
239
|
function info(message) {
|
242
240
|
log.info(`${fullTitle} =>`, message);
|
@@ -269,7 +267,7 @@ function credentialLoggerInstance(title, parent, log = logger$q) {
|
|
269
267
|
* `[title] => getToken() => [message]`
|
270
268
|
*
|
271
269
|
*/
|
272
|
-
function credentialLogger(title, log = logger$
|
270
|
+
function credentialLogger(title, log = logger$l) {
|
273
271
|
const credLogger = credentialLoggerInstance(title, undefined, log);
|
274
272
|
return Object.assign(Object.assign({}, credLogger), { parent: log, getToken: credentialLoggerInstance("=> getToken()", credLogger, log) });
|
275
273
|
}
|
@@ -497,8 +495,6 @@ const DefaultScopeSuffix = "/.default";
|
|
497
495
|
const imdsHost = "http://169.254.169.254";
|
498
496
|
const imdsEndpointPath = "/metadata/identity/oauth2/token";
|
499
497
|
const imdsApiVersion = "2018-02-01";
|
500
|
-
const azureArcAPIVersion = "2019-11-01";
|
501
|
-
const azureFabricVersion = "2019-07-01-preview";
|
502
498
|
|
503
499
|
// Copyright (c) Microsoft Corporation.
|
504
500
|
// Licensed under the MIT license.
|
@@ -590,14 +586,19 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
590
586
|
} }, options), { userAgentOptions: {
|
591
587
|
userAgentPrefix,
|
592
588
|
}, baseUri }));
|
589
|
+
this.allowInsecureConnection = false;
|
593
590
|
this.authorityHost = baseUri;
|
594
591
|
this.abortControllers = new Map();
|
595
592
|
this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
|
596
593
|
// used for WorkloadIdentity
|
597
594
|
this.tokenCredentialOptions = Object.assign({}, options);
|
595
|
+
// used for ManagedIdentity
|
596
|
+
if (options === null || options === void 0 ? void 0 : options.allowInsecureConnection) {
|
597
|
+
this.allowInsecureConnection = options.allowInsecureConnection;
|
598
|
+
}
|
598
599
|
}
|
599
600
|
async sendTokenRequest(request) {
|
600
|
-
logger$
|
601
|
+
logger$l.info(`IdentityClient: sending token request to [${request.url}]`);
|
601
602
|
const response = await this.sendRequest(request);
|
602
603
|
if (response.bodyAsText && (response.status === 200 || response.status === 201)) {
|
603
604
|
const parsedBody = JSON.parse(response.bodyAsText);
|
@@ -612,12 +613,12 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
612
613
|
},
|
613
614
|
refreshToken: parsedBody.refresh_token,
|
614
615
|
};
|
615
|
-
logger$
|
616
|
+
logger$l.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
|
616
617
|
return token;
|
617
618
|
}
|
618
619
|
else {
|
619
620
|
const error = new AuthenticationError(response.status, response.bodyAsText);
|
620
|
-
logger$
|
621
|
+
logger$l.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
|
621
622
|
throw error;
|
622
623
|
}
|
623
624
|
}
|
@@ -625,7 +626,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
625
626
|
if (refreshToken === undefined) {
|
626
627
|
return null;
|
627
628
|
}
|
628
|
-
logger$
|
629
|
+
logger$l.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
|
629
630
|
const refreshParams = {
|
630
631
|
grant_type: "refresh_token",
|
631
632
|
client_id: clientId,
|
@@ -651,7 +652,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
651
652
|
tracingOptions: updatedOptions.tracingOptions,
|
652
653
|
});
|
653
654
|
const response = await this.sendTokenRequest(request);
|
654
|
-
logger$
|
655
|
+
logger$l.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
|
655
656
|
return response;
|
656
657
|
}
|
657
658
|
catch (err) {
|
@@ -660,11 +661,11 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
660
661
|
// It's likely that the refresh token has expired, so
|
661
662
|
// return null so that the credential implementation will
|
662
663
|
// initiate the authentication flow again.
|
663
|
-
logger$
|
664
|
+
logger$l.info(`IdentityClient: interaction required for client ID: ${clientId}`);
|
664
665
|
return null;
|
665
666
|
}
|
666
667
|
else {
|
667
|
-
logger$
|
668
|
+
logger$l.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`);
|
668
669
|
throw err;
|
669
670
|
}
|
670
671
|
}
|
@@ -712,6 +713,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
712
713
|
url,
|
713
714
|
method: "GET",
|
714
715
|
body: options === null || options === void 0 ? void 0 : options.body,
|
716
|
+
allowInsecureConnection: this.allowInsecureConnection,
|
715
717
|
headers: coreRestPipeline.createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
|
716
718
|
abortSignal: this.generateAbortSignal(noCorrelationId),
|
717
719
|
});
|
@@ -729,6 +731,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
729
731
|
method: "POST",
|
730
732
|
body: options === null || options === void 0 ? void 0 : options.body,
|
731
733
|
headers: coreRestPipeline.createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
|
734
|
+
allowInsecureConnection: this.allowInsecureConnection,
|
732
735
|
// MSAL doesn't send the correlation ID on the get requests.
|
733
736
|
abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),
|
734
737
|
});
|
@@ -773,10 +776,10 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
773
776
|
}
|
774
777
|
const base64Metadata = accessToken.split(".")[1];
|
775
778
|
const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8"));
|
776
|
-
logger$
|
779
|
+
logger$l.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`);
|
777
780
|
}
|
778
781
|
catch (e) {
|
779
|
-
logger$
|
782
|
+
logger$l.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
|
780
783
|
}
|
781
784
|
}
|
782
785
|
}
|
@@ -785,7 +788,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
785
788
|
// Licensed under the MIT license.
|
786
789
|
const CommonTenantId = "common";
|
787
790
|
const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
|
788
|
-
const logger$
|
791
|
+
const logger$k = credentialLogger("VisualStudioCodeCredential");
|
789
792
|
let findCredentials = undefined;
|
790
793
|
const vsCodeCredentialControl = {
|
791
794
|
setVsCodeCredentialFinder(finder) {
|
@@ -838,7 +841,7 @@ function getPropertyFromVSCode(property) {
|
|
838
841
|
}
|
839
842
|
}
|
840
843
|
catch (e) {
|
841
|
-
logger$
|
844
|
+
logger$k.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
|
842
845
|
return;
|
843
846
|
}
|
844
847
|
}
|
@@ -871,7 +874,7 @@ class VisualStudioCodeCredential {
|
|
871
874
|
const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
|
872
875
|
this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
|
873
876
|
if (options && options.tenantId) {
|
874
|
-
checkTenantId(logger$
|
877
|
+
checkTenantId(logger$k, options.tenantId);
|
875
878
|
this.tenantId = options.tenantId;
|
876
879
|
}
|
877
880
|
else {
|
@@ -911,7 +914,7 @@ class VisualStudioCodeCredential {
|
|
911
914
|
async getToken(scopes, options) {
|
912
915
|
var _a, _b;
|
913
916
|
await this.prepareOnce();
|
914
|
-
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$
|
917
|
+
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$k) || this.tenantId;
|
915
918
|
if (findCredentials === undefined) {
|
916
919
|
throw new CredentialUnavailableError([
|
917
920
|
"No implementation of `VisualStudioCodeCredential` is available.",
|
@@ -925,7 +928,7 @@ class VisualStudioCodeCredential {
|
|
925
928
|
// Check to make sure the scope we get back is a valid scope
|
926
929
|
if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
927
930
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
928
|
-
logger$
|
931
|
+
logger$k.getToken.info(formatError(scopes, error));
|
929
932
|
throw error;
|
930
933
|
}
|
931
934
|
if (scopeString.indexOf("offline_access") < 0) {
|
@@ -945,18 +948,18 @@ class VisualStudioCodeCredential {
|
|
945
948
|
if (refreshToken) {
|
946
949
|
const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
|
947
950
|
if (tokenResponse) {
|
948
|
-
logger$
|
951
|
+
logger$k.getToken.info(formatSuccess(scopes));
|
949
952
|
return tokenResponse.accessToken;
|
950
953
|
}
|
951
954
|
else {
|
952
955
|
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.");
|
953
|
-
logger$
|
956
|
+
logger$k.getToken.info(formatError(scopes, error));
|
954
957
|
throw error;
|
955
958
|
}
|
956
959
|
}
|
957
960
|
else {
|
958
961
|
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.");
|
959
|
-
logger$
|
962
|
+
logger$k.getToken.info(formatError(scopes, error));
|
960
963
|
throw error;
|
961
964
|
}
|
962
965
|
}
|
@@ -1005,438 +1008,6 @@ function useIdentityPlugin(plugin) {
|
|
1005
1008
|
plugin(pluginContext);
|
1006
1009
|
}
|
1007
1010
|
|
1008
|
-
// Copyright (c) Microsoft Corporation.
|
1009
|
-
// Licensed under the MIT license.
|
1010
|
-
const msiName$6 = "ManagedIdentityCredential - CloudShellMSI";
|
1011
|
-
const logger$o = credentialLogger(msiName$6);
|
1012
|
-
/**
|
1013
|
-
* Generates the options used on the request for an access token.
|
1014
|
-
*/
|
1015
|
-
function prepareRequestOptions$5(scopes, clientId, resourceId) {
|
1016
|
-
const resource = mapScopesToResource(scopes);
|
1017
|
-
if (!resource) {
|
1018
|
-
throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
|
1019
|
-
}
|
1020
|
-
const body = {
|
1021
|
-
resource,
|
1022
|
-
};
|
1023
|
-
if (clientId) {
|
1024
|
-
body.client_id = clientId;
|
1025
|
-
}
|
1026
|
-
if (resourceId) {
|
1027
|
-
body.msi_res_id = resourceId;
|
1028
|
-
}
|
1029
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
1030
|
-
if (!process.env.MSI_ENDPOINT) {
|
1031
|
-
throw new Error(`${msiName$6}: Missing environment variable: MSI_ENDPOINT`);
|
1032
|
-
}
|
1033
|
-
const params = new URLSearchParams(body);
|
1034
|
-
return {
|
1035
|
-
url: process.env.MSI_ENDPOINT,
|
1036
|
-
method: "POST",
|
1037
|
-
body: params.toString(),
|
1038
|
-
headers: coreRestPipeline.createHttpHeaders({
|
1039
|
-
Accept: "application/json",
|
1040
|
-
Metadata: "true",
|
1041
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
1042
|
-
}),
|
1043
|
-
};
|
1044
|
-
}
|
1045
|
-
/**
|
1046
|
-
* Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
|
1047
|
-
* Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
|
1048
|
-
*/
|
1049
|
-
const cloudShellMsi = {
|
1050
|
-
name: "cloudShellMsi",
|
1051
|
-
async isAvailable({ scopes }) {
|
1052
|
-
const resource = mapScopesToResource(scopes);
|
1053
|
-
if (!resource) {
|
1054
|
-
logger$o.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
|
1055
|
-
return false;
|
1056
|
-
}
|
1057
|
-
const result = Boolean(process.env.MSI_ENDPOINT);
|
1058
|
-
if (!result) {
|
1059
|
-
logger$o.info(`${msiName$6}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
|
1060
|
-
}
|
1061
|
-
return result;
|
1062
|
-
},
|
1063
|
-
async getToken(configuration, getTokenOptions = {}) {
|
1064
|
-
const { identityClient, scopes, clientId, resourceId } = configuration;
|
1065
|
-
if (clientId) {
|
1066
|
-
logger$o.warning(`${msiName$6}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
1067
|
-
}
|
1068
|
-
if (resourceId) {
|
1069
|
-
logger$o.warning(`${msiName$6}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
1070
|
-
}
|
1071
|
-
logger$o.info(`${msiName$6}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
1072
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId, resourceId)), {
|
1073
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
1074
|
-
allowInsecureConnection: true }));
|
1075
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
1076
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
1077
|
-
},
|
1078
|
-
};
|
1079
|
-
|
1080
|
-
// Copyright (c) Microsoft Corporation.
|
1081
|
-
// Licensed under the MIT license.
|
1082
|
-
const msiName$5 = "ManagedIdentityCredential - AppServiceMSI 2017";
|
1083
|
-
const logger$n = credentialLogger(msiName$5);
|
1084
|
-
/**
|
1085
|
-
* Generates the options used on the request for an access token.
|
1086
|
-
*/
|
1087
|
-
function prepareRequestOptions$4(scopes, clientId) {
|
1088
|
-
const resource = mapScopesToResource(scopes);
|
1089
|
-
if (!resource) {
|
1090
|
-
throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
|
1091
|
-
}
|
1092
|
-
const queryParameters = {
|
1093
|
-
resource,
|
1094
|
-
"api-version": "2017-09-01",
|
1095
|
-
};
|
1096
|
-
if (clientId) {
|
1097
|
-
queryParameters.clientid = clientId;
|
1098
|
-
}
|
1099
|
-
const query = new URLSearchParams(queryParameters);
|
1100
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
1101
|
-
if (!process.env.MSI_ENDPOINT) {
|
1102
|
-
throw new Error(`${msiName$5}: Missing environment variable: MSI_ENDPOINT`);
|
1103
|
-
}
|
1104
|
-
if (!process.env.MSI_SECRET) {
|
1105
|
-
throw new Error(`${msiName$5}: Missing environment variable: MSI_SECRET`);
|
1106
|
-
}
|
1107
|
-
return {
|
1108
|
-
url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
|
1109
|
-
method: "GET",
|
1110
|
-
headers: coreRestPipeline.createHttpHeaders({
|
1111
|
-
Accept: "application/json",
|
1112
|
-
secret: process.env.MSI_SECRET,
|
1113
|
-
}),
|
1114
|
-
};
|
1115
|
-
}
|
1116
|
-
/**
|
1117
|
-
* 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.
|
1118
|
-
*/
|
1119
|
-
const appServiceMsi2017 = {
|
1120
|
-
name: "appServiceMsi2017",
|
1121
|
-
async isAvailable({ scopes }) {
|
1122
|
-
const resource = mapScopesToResource(scopes);
|
1123
|
-
if (!resource) {
|
1124
|
-
logger$n.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
|
1125
|
-
return false;
|
1126
|
-
}
|
1127
|
-
const env = process.env;
|
1128
|
-
const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
|
1129
|
-
if (!result) {
|
1130
|
-
logger$n.info(`${msiName$5}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
|
1131
|
-
}
|
1132
|
-
return result;
|
1133
|
-
},
|
1134
|
-
async getToken(configuration, getTokenOptions = {}) {
|
1135
|
-
const { identityClient, scopes, clientId, resourceId } = configuration;
|
1136
|
-
if (resourceId) {
|
1137
|
-
logger$n.warning(`${msiName$5}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
1138
|
-
}
|
1139
|
-
logger$n.info(`${msiName$5}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
1140
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId)), {
|
1141
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
1142
|
-
allowInsecureConnection: true }));
|
1143
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
1144
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
1145
|
-
},
|
1146
|
-
};
|
1147
|
-
|
1148
|
-
// Copyright (c) Microsoft Corporation.
|
1149
|
-
// Licensed under the MIT license.
|
1150
|
-
const msiName$4 = "ManagedIdentityCredential - AppServiceMSI 2019";
|
1151
|
-
const logger$m = credentialLogger(msiName$4);
|
1152
|
-
/**
|
1153
|
-
* Generates the options used on the request for an access token.
|
1154
|
-
*/
|
1155
|
-
function prepareRequestOptions$3(scopes, clientId, resourceId) {
|
1156
|
-
const resource = mapScopesToResource(scopes);
|
1157
|
-
if (!resource) {
|
1158
|
-
throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
|
1159
|
-
}
|
1160
|
-
const queryParameters = {
|
1161
|
-
resource,
|
1162
|
-
"api-version": "2019-08-01",
|
1163
|
-
};
|
1164
|
-
if (clientId) {
|
1165
|
-
queryParameters.client_id = clientId;
|
1166
|
-
}
|
1167
|
-
if (resourceId) {
|
1168
|
-
queryParameters.mi_res_id = resourceId;
|
1169
|
-
}
|
1170
|
-
const query = new URLSearchParams(queryParameters);
|
1171
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
1172
|
-
if (!process.env.IDENTITY_ENDPOINT) {
|
1173
|
-
throw new Error(`${msiName$4}: Missing environment variable: IDENTITY_ENDPOINT`);
|
1174
|
-
}
|
1175
|
-
if (!process.env.IDENTITY_HEADER) {
|
1176
|
-
throw new Error(`${msiName$4}: Missing environment variable: IDENTITY_HEADER`);
|
1177
|
-
}
|
1178
|
-
return {
|
1179
|
-
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
1180
|
-
method: "GET",
|
1181
|
-
headers: coreRestPipeline.createHttpHeaders({
|
1182
|
-
Accept: "application/json",
|
1183
|
-
"X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
|
1184
|
-
}),
|
1185
|
-
};
|
1186
|
-
}
|
1187
|
-
/**
|
1188
|
-
* 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.
|
1189
|
-
*/
|
1190
|
-
const appServiceMsi2019 = {
|
1191
|
-
name: "appServiceMsi2019",
|
1192
|
-
async isAvailable({ scopes }) {
|
1193
|
-
const resource = mapScopesToResource(scopes);
|
1194
|
-
if (!resource) {
|
1195
|
-
logger$m.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
|
1196
|
-
return false;
|
1197
|
-
}
|
1198
|
-
const env = process.env;
|
1199
|
-
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
|
1200
|
-
if (!result) {
|
1201
|
-
logger$m.info(`${msiName$4}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
|
1202
|
-
}
|
1203
|
-
return result;
|
1204
|
-
},
|
1205
|
-
async getToken(configuration, getTokenOptions = {}) {
|
1206
|
-
const { identityClient, scopes, clientId, resourceId } = configuration;
|
1207
|
-
logger$m.info(`${msiName$4}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
1208
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), {
|
1209
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
1210
|
-
allowInsecureConnection: true }));
|
1211
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
1212
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
1213
|
-
},
|
1214
|
-
};
|
1215
|
-
|
1216
|
-
// Copyright (c) Microsoft Corporation.
|
1217
|
-
// Licensed under the MIT license.
|
1218
|
-
const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
|
1219
|
-
const logger$l = credentialLogger(msiName$3);
|
1220
|
-
/**
|
1221
|
-
* Generates the options used on the request for an access token.
|
1222
|
-
*/
|
1223
|
-
function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
1224
|
-
const resource = mapScopesToResource(scopes);
|
1225
|
-
if (!resource) {
|
1226
|
-
throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
|
1227
|
-
}
|
1228
|
-
const queryParameters = {
|
1229
|
-
resource,
|
1230
|
-
"api-version": azureArcAPIVersion,
|
1231
|
-
};
|
1232
|
-
if (clientId) {
|
1233
|
-
queryParameters.client_id = clientId;
|
1234
|
-
}
|
1235
|
-
if (resourceId) {
|
1236
|
-
queryParameters.msi_res_id = resourceId;
|
1237
|
-
}
|
1238
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
1239
|
-
if (!process.env.IDENTITY_ENDPOINT) {
|
1240
|
-
throw new Error(`${msiName$3}: Missing environment variable: IDENTITY_ENDPOINT`);
|
1241
|
-
}
|
1242
|
-
const query = new URLSearchParams(queryParameters);
|
1243
|
-
return coreRestPipeline.createPipelineRequest({
|
1244
|
-
// Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
|
1245
|
-
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
1246
|
-
method: "GET",
|
1247
|
-
headers: coreRestPipeline.createHttpHeaders({
|
1248
|
-
Accept: "application/json",
|
1249
|
-
Metadata: "true",
|
1250
|
-
}),
|
1251
|
-
});
|
1252
|
-
}
|
1253
|
-
/**
|
1254
|
-
* Does a request to the authentication provider that results in a file path.
|
1255
|
-
*/
|
1256
|
-
async function filePathRequest(identityClient, requestPrepareOptions) {
|
1257
|
-
const response = await identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
|
1258
|
-
if (response.status !== 401) {
|
1259
|
-
let message = "";
|
1260
|
-
if (response.bodyAsText) {
|
1261
|
-
message = ` Response: ${response.bodyAsText}`;
|
1262
|
-
}
|
1263
|
-
throw new AuthenticationError(response.status, `${msiName$3}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
|
1264
|
-
}
|
1265
|
-
const authHeader = response.headers.get("www-authenticate") || "";
|
1266
|
-
try {
|
1267
|
-
return authHeader.split("=").slice(1)[0];
|
1268
|
-
}
|
1269
|
-
catch (e) {
|
1270
|
-
throw Error(`Invalid www-authenticate header format: ${authHeader}`);
|
1271
|
-
}
|
1272
|
-
}
|
1273
|
-
function platformToFilePath() {
|
1274
|
-
switch (process.platform) {
|
1275
|
-
case "win32":
|
1276
|
-
if (!process.env.PROGRAMDATA) {
|
1277
|
-
throw new Error(`${msiName$3}: PROGRAMDATA environment variable has no value.`);
|
1278
|
-
}
|
1279
|
-
return `${process.env.PROGRAMDATA}\\AzureConnectedMachineAgent\\Tokens`;
|
1280
|
-
case "linux":
|
1281
|
-
return "/var/opt/azcmagent/tokens";
|
1282
|
-
default:
|
1283
|
-
throw new Error(`${msiName$3}: Unsupported platform ${process.platform}.`);
|
1284
|
-
}
|
1285
|
-
}
|
1286
|
-
/**
|
1287
|
-
* Validates that a given Azure Arc MSI file path is valid for use.
|
1288
|
-
*
|
1289
|
-
* A valid file will:
|
1290
|
-
* 1. Be in the expected path for the current platform.
|
1291
|
-
* 2. Have a `.key` extension.
|
1292
|
-
* 3. Be at most 4096 bytes in size.
|
1293
|
-
*/
|
1294
|
-
function validateKeyFile(filePath) {
|
1295
|
-
if (!filePath) {
|
1296
|
-
throw new Error(`${msiName$3}: Failed to find the token file.`);
|
1297
|
-
}
|
1298
|
-
if (!filePath.endsWith(".key")) {
|
1299
|
-
throw new Error(`${msiName$3}: unexpected file path from HIMDS service: ${filePath}.`);
|
1300
|
-
}
|
1301
|
-
const expectedPath = platformToFilePath();
|
1302
|
-
if (!filePath.startsWith(expectedPath)) {
|
1303
|
-
throw new Error(`${msiName$3}: unexpected file path from HIMDS service: ${filePath}.`);
|
1304
|
-
}
|
1305
|
-
const stats = fs$1.statSync(filePath);
|
1306
|
-
if (stats.size > 4096) {
|
1307
|
-
throw new Error(`${msiName$3}: The file at ${filePath} is larger than expected at ${stats.size} bytes.`);
|
1308
|
-
}
|
1309
|
-
}
|
1310
|
-
/**
|
1311
|
-
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
|
1312
|
-
*/
|
1313
|
-
const arcMsi = {
|
1314
|
-
name: "arc",
|
1315
|
-
async isAvailable({ scopes }) {
|
1316
|
-
const resource = mapScopesToResource(scopes);
|
1317
|
-
if (!resource) {
|
1318
|
-
logger$l.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
|
1319
|
-
return false;
|
1320
|
-
}
|
1321
|
-
const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
|
1322
|
-
if (!result) {
|
1323
|
-
logger$l.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
|
1324
|
-
}
|
1325
|
-
return result;
|
1326
|
-
},
|
1327
|
-
async getToken(configuration, getTokenOptions = {}) {
|
1328
|
-
var _a;
|
1329
|
-
const { identityClient, scopes, clientId, resourceId } = configuration;
|
1330
|
-
if (clientId) {
|
1331
|
-
logger$l.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
1332
|
-
}
|
1333
|
-
if (resourceId) {
|
1334
|
-
logger$l.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
|
1335
|
-
}
|
1336
|
-
logger$l.info(`${msiName$3}: Authenticating.`);
|
1337
|
-
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
1338
|
-
const filePath = await filePathRequest(identityClient, requestOptions);
|
1339
|
-
validateKeyFile(filePath);
|
1340
|
-
const key = await fs$1.promises.readFile(filePath, { encoding: "utf-8" });
|
1341
|
-
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
1342
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
|
1343
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
1344
|
-
allowInsecureConnection: true }));
|
1345
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
1346
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
1347
|
-
},
|
1348
|
-
};
|
1349
|
-
|
1350
|
-
// Copyright (c) Microsoft Corporation.
|
1351
|
-
// Licensed under the MIT license.
|
1352
|
-
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
|
1353
|
-
//
|
1354
|
-
// FROM node:12
|
1355
|
-
// RUN wget https://host.any/path/bash.sh
|
1356
|
-
// CMD ["bash", "bash.sh"]
|
1357
|
-
//
|
1358
|
-
// Where the bash script contains:
|
1359
|
-
//
|
1360
|
-
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
1361
|
-
//
|
1362
|
-
const msiName$2 = "ManagedIdentityCredential - Fabric MSI";
|
1363
|
-
const logger$k = credentialLogger(msiName$2);
|
1364
|
-
/**
|
1365
|
-
* Generates the options used on the request for an access token.
|
1366
|
-
*/
|
1367
|
-
function prepareRequestOptions$1(scopes, clientId, resourceId) {
|
1368
|
-
const resource = mapScopesToResource(scopes);
|
1369
|
-
if (!resource) {
|
1370
|
-
throw new Error(`${msiName$2}: Multiple scopes are not supported.`);
|
1371
|
-
}
|
1372
|
-
const queryParameters = {
|
1373
|
-
resource,
|
1374
|
-
"api-version": azureFabricVersion,
|
1375
|
-
};
|
1376
|
-
if (clientId) {
|
1377
|
-
queryParameters.client_id = clientId;
|
1378
|
-
}
|
1379
|
-
if (resourceId) {
|
1380
|
-
queryParameters.msi_res_id = resourceId;
|
1381
|
-
}
|
1382
|
-
const query = new URLSearchParams(queryParameters);
|
1383
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
1384
|
-
if (!process.env.IDENTITY_ENDPOINT) {
|
1385
|
-
throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
|
1386
|
-
}
|
1387
|
-
if (!process.env.IDENTITY_HEADER) {
|
1388
|
-
throw new Error("Missing environment variable: IDENTITY_HEADER");
|
1389
|
-
}
|
1390
|
-
return {
|
1391
|
-
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
1392
|
-
method: "GET",
|
1393
|
-
headers: coreRestPipeline.createHttpHeaders({
|
1394
|
-
Accept: "application/json",
|
1395
|
-
secret: process.env.IDENTITY_HEADER,
|
1396
|
-
}),
|
1397
|
-
};
|
1398
|
-
}
|
1399
|
-
/**
|
1400
|
-
* Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
|
1401
|
-
*/
|
1402
|
-
const fabricMsi = {
|
1403
|
-
name: "fabricMsi",
|
1404
|
-
async isAvailable({ scopes }) {
|
1405
|
-
const resource = mapScopesToResource(scopes);
|
1406
|
-
if (!resource) {
|
1407
|
-
logger$k.info(`${msiName$2}: Unavailable. Multiple scopes are not supported.`);
|
1408
|
-
return false;
|
1409
|
-
}
|
1410
|
-
const env = process.env;
|
1411
|
-
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
|
1412
|
-
if (!result) {
|
1413
|
-
logger$k.info(`${msiName$2}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
|
1414
|
-
}
|
1415
|
-
return result;
|
1416
|
-
},
|
1417
|
-
async getToken(configuration, getTokenOptions = {}) {
|
1418
|
-
const { scopes, identityClient, clientId, resourceId } = configuration;
|
1419
|
-
if (resourceId) {
|
1420
|
-
logger$k.warning(`${msiName$2}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
1421
|
-
}
|
1422
|
-
logger$k.info([
|
1423
|
-
`${msiName$2}:`,
|
1424
|
-
"Using the endpoint and the secret coming from the environment variables:",
|
1425
|
-
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
|
1426
|
-
"IDENTITY_HEADER=[REDACTED] and",
|
1427
|
-
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
|
1428
|
-
].join(" "));
|
1429
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
|
1430
|
-
request.agent = new https.Agent({
|
1431
|
-
// This is necessary because Service Fabric provides a self-signed certificate.
|
1432
|
-
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
1433
|
-
rejectUnauthorized: false,
|
1434
|
-
});
|
1435
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
1436
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
1437
|
-
},
|
1438
|
-
};
|
1439
|
-
|
1440
1011
|
// Copyright (c) Microsoft Corporation.
|
1441
1012
|
// Licensed under the MIT license.
|
1442
1013
|
/**
|
@@ -1776,6 +1347,41 @@ const imdsMsi = {
|
|
1776
1347
|
},
|
1777
1348
|
};
|
1778
1349
|
|
1350
|
+
// Copyright (c) Microsoft Corporation.
|
1351
|
+
// Licensed under the MIT license.
|
1352
|
+
// Matches the default retry configuration in expontentialRetryStrategy.ts
|
1353
|
+
const DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;
|
1354
|
+
/**
|
1355
|
+
* An additional policy that retries on 404 errors. The default retry policy does not retry on
|
1356
|
+
* 404s, but the IMDS endpoint can return 404s when the token is not yet available. This policy
|
1357
|
+
* will retry on 404s with an exponential backoff.
|
1358
|
+
*
|
1359
|
+
* @param msiRetryConfig - The retry configuration for the MSI credential.
|
1360
|
+
* @returns - The policy that will retry on 404s.
|
1361
|
+
*/
|
1362
|
+
function imdsRetryPolicy(msiRetryConfig) {
|
1363
|
+
return coreRestPipeline.retryPolicy([
|
1364
|
+
{
|
1365
|
+
name: "imdsRetryPolicy",
|
1366
|
+
retry: ({ retryCount, response }) => {
|
1367
|
+
if ((response === null || response === void 0 ? void 0 : response.status) !== 404) {
|
1368
|
+
return { skipStrategy: true };
|
1369
|
+
}
|
1370
|
+
// Exponentially increase the delay each time
|
1371
|
+
const exponentialDelay = msiRetryConfig.startDelayInMs * Math.pow(2, retryCount);
|
1372
|
+
// Don't let the delay exceed the maximum
|
1373
|
+
const clampedExponentialDelay = Math.min(DEFAULT_CLIENT_MAX_RETRY_INTERVAL, exponentialDelay);
|
1374
|
+
// Allow the final value to have some "jitter" (within 50% of the delay size) so
|
1375
|
+
// that retries across multiple clients don't occur simultaneously.
|
1376
|
+
const retryAfterInMs = clampedExponentialDelay / 2 + coreUtil.getRandomIntegerInclusive(0, clampedExponentialDelay / 2);
|
1377
|
+
return { retryAfterInMs };
|
1378
|
+
},
|
1379
|
+
},
|
1380
|
+
], {
|
1381
|
+
maxRetries: msiRetryConfig.maxRetries,
|
1382
|
+
});
|
1383
|
+
}
|
1384
|
+
|
1779
1385
|
// Copyright (c) Microsoft Corporation.
|
1780
1386
|
// Licensed under the MIT license.
|
1781
1387
|
/**
|
@@ -1956,7 +1562,7 @@ function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) {
|
|
1956
1562
|
networkClient: httpClient,
|
1957
1563
|
loggerOptions: {
|
1958
1564
|
loggerCallback: defaultLoggerCallback((_c = msalClientOptions.logger) !== null && _c !== void 0 ? _c : msalLogger),
|
1959
|
-
logLevel: getMSALLogLevel(logger$
|
1565
|
+
logLevel: getMSALLogLevel(logger$m.getLogLevel()),
|
1960
1566
|
piiLoggingEnabled: (_d = msalClientOptions.loggingOptions) === null || _d === void 0 ? void 0 : _d.enableUnsafeSupportLogging,
|
1961
1567
|
},
|
1962
1568
|
},
|
@@ -2509,132 +2115,76 @@ const logger$f = credentialLogger(msiName);
|
|
2509
2115
|
/**
|
2510
2116
|
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
|
2511
2117
|
*/
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
2521
|
-
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
|
2528
|
-
|
2529
|
-
|
2530
|
-
|
2531
|
-
},
|
2532
|
-
};
|
2533
|
-
}
|
2118
|
+
const tokenExchangeMsi = {
|
2119
|
+
name: "tokenExchangeMsi",
|
2120
|
+
async isAvailable({ clientId }) {
|
2121
|
+
const env = process.env;
|
2122
|
+
const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
|
2123
|
+
env.AZURE_TENANT_ID &&
|
2124
|
+
process.env.AZURE_FEDERATED_TOKEN_FILE);
|
2125
|
+
if (!result) {
|
2126
|
+
logger$f.info(`${msiName}: 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`);
|
2127
|
+
}
|
2128
|
+
return result;
|
2129
|
+
},
|
2130
|
+
async getToken(configuration, getTokenOptions = {}) {
|
2131
|
+
const { scopes, clientId } = configuration;
|
2132
|
+
const identityClientTokenCredentialOptions = {};
|
2133
|
+
const workloadIdentityCredential = new WorkloadIdentityCredential(Object.assign(Object.assign({ clientId, tenantId: process.env.AZURE_TENANT_ID, tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE }, identityClientTokenCredentialOptions), { disableInstanceDiscovery: true }));
|
2134
|
+
return workloadIdentityCredential.getToken(scopes, getTokenOptions);
|
2135
|
+
},
|
2136
|
+
};
|
2534
2137
|
|
2535
2138
|
// Copyright (c) Microsoft Corporation.
|
2536
2139
|
// Licensed under the MIT license.
|
2537
|
-
const logger$e = credentialLogger("ManagedIdentityCredential");
|
2538
|
-
class
|
2539
|
-
constructor(clientIdOrOptions, options) {
|
2140
|
+
const logger$e = credentialLogger("ManagedIdentityCredential(MSAL)");
|
2141
|
+
class MsalMsiProvider {
|
2142
|
+
constructor(clientIdOrOptions, options = {}) {
|
2540
2143
|
var _a, _b;
|
2541
|
-
this.isEndpointUnavailable = null;
|
2542
|
-
this.isAppTokenProviderInitialized = false;
|
2543
2144
|
this.msiRetryConfig = {
|
2544
2145
|
maxRetries: 5,
|
2545
2146
|
startDelayInMs: 800,
|
2546
2147
|
intervalIncrement: 2,
|
2547
2148
|
};
|
2548
|
-
let _options;
|
2149
|
+
let _options = {};
|
2549
2150
|
if (typeof clientIdOrOptions === "string") {
|
2550
2151
|
this.clientId = clientIdOrOptions;
|
2551
2152
|
_options = options;
|
2552
2153
|
}
|
2553
2154
|
else {
|
2554
2155
|
this.clientId = clientIdOrOptions === null || clientIdOrOptions === void 0 ? void 0 : clientIdOrOptions.clientId;
|
2555
|
-
_options = clientIdOrOptions;
|
2156
|
+
_options = clientIdOrOptions !== null && clientIdOrOptions !== void 0 ? clientIdOrOptions : {};
|
2556
2157
|
}
|
2557
2158
|
this.resourceId = _options === null || _options === void 0 ? void 0 : _options.resourceId;
|
2558
2159
|
// For JavaScript users.
|
2559
2160
|
if (this.clientId && this.resourceId) {
|
2560
2161
|
throw new Error(`ManagedIdentityCredential - Client Id and Resource Id can't be provided at the same time.`);
|
2561
2162
|
}
|
2163
|
+
// ManagedIdentity uses http for local requests
|
2164
|
+
_options.allowInsecureConnection = true;
|
2562
2165
|
if (((_a = _options === null || _options === void 0 ? void 0 : _options.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== undefined) {
|
2563
2166
|
this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;
|
2564
2167
|
}
|
2565
|
-
this.identityClient = new IdentityClient(_options);
|
2566
|
-
this.
|
2567
|
-
|
2568
|
-
|
2569
|
-
|
2570
|
-
* since this wasn't done previously before adding token cache support
|
2571
|
-
*/
|
2572
|
-
this.confidentialApp = new msalCommon.ConfidentialClientApplication({
|
2573
|
-
auth: {
|
2574
|
-
authority: "https://login.microsoftonline.com/managed_identity",
|
2575
|
-
clientId: (_b = this.clientId) !== null && _b !== void 0 ? _b : DeveloperSignOnClientId,
|
2576
|
-
clientSecret: "dummy-secret",
|
2577
|
-
cloudDiscoveryMetadata: '{"tenant_discovery_endpoint":"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}',
|
2578
|
-
authorityMetadata: '{"token_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/common/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"kerberos_endpoint":"https://login.microsoftonline.com/common/kerberos","tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}',
|
2579
|
-
clientCapabilities: [],
|
2168
|
+
this.identityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { additionalPolicies: [{ policy: imdsRetryPolicy(this.msiRetryConfig), position: "perCall" }] }));
|
2169
|
+
this.managedIdentityApp = new msalCommon.ManagedIdentityApplication({
|
2170
|
+
managedIdentityIdParams: {
|
2171
|
+
userAssignedClientId: this.clientId,
|
2172
|
+
userAssignedResourceId: this.resourceId,
|
2580
2173
|
},
|
2581
2174
|
system: {
|
2175
|
+
// todo: proxyUrl?
|
2176
|
+
disableInternalRetries: true,
|
2177
|
+
networkClient: this.identityClient,
|
2582
2178
|
loggerOptions: {
|
2583
|
-
logLevel: getMSALLogLevel(logger$
|
2179
|
+
logLevel: getMSALLogLevel(logger$m.getLogLevel()),
|
2180
|
+
piiLoggingEnabled: (_b = options.loggingOptions) === null || _b === void 0 ? void 0 : _b.enableUnsafeSupportLogging,
|
2181
|
+
loggerCallback: defaultLoggerCallback(logger$e),
|
2584
2182
|
},
|
2585
2183
|
},
|
2586
2184
|
});
|
2587
|
-
|
2588
|
-
|
2589
|
-
|
2590
|
-
return this.cachedMSI;
|
2591
|
-
}
|
2592
|
-
const MSIs = [
|
2593
|
-
arcMsi,
|
2594
|
-
fabricMsi,
|
2595
|
-
appServiceMsi2019,
|
2596
|
-
appServiceMsi2017,
|
2597
|
-
cloudShellMsi,
|
2598
|
-
tokenExchangeMsi(),
|
2599
|
-
imdsMsi,
|
2600
|
-
];
|
2601
|
-
for (const msi of MSIs) {
|
2602
|
-
if (await msi.isAvailable({
|
2603
|
-
scopes,
|
2604
|
-
identityClient: this.isAvailableIdentityClient,
|
2605
|
-
clientId: this.clientId,
|
2606
|
-
resourceId: this.resourceId,
|
2607
|
-
getTokenOptions,
|
2608
|
-
})) {
|
2609
|
-
this.cachedMSI = msi;
|
2610
|
-
return msi;
|
2611
|
-
}
|
2612
|
-
}
|
2613
|
-
throw new CredentialUnavailableError(`ManagedIdentityCredential - No MSI credential available`);
|
2614
|
-
}
|
2615
|
-
async authenticateManagedIdentity(scopes, getTokenOptions) {
|
2616
|
-
const { span, updatedOptions } = tracingClient.startSpan(`ManagedIdentityCredential.authenticateManagedIdentity`, getTokenOptions);
|
2617
|
-
try {
|
2618
|
-
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
|
2619
|
-
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
|
2620
|
-
return availableMSI.getToken({
|
2621
|
-
identityClient: this.identityClient,
|
2622
|
-
scopes,
|
2623
|
-
clientId: this.clientId,
|
2624
|
-
resourceId: this.resourceId,
|
2625
|
-
retryConfig: this.msiRetryConfig,
|
2626
|
-
}, updatedOptions);
|
2627
|
-
}
|
2628
|
-
catch (err) {
|
2629
|
-
span.setStatus({
|
2630
|
-
status: "error",
|
2631
|
-
error: err,
|
2632
|
-
});
|
2633
|
-
throw err;
|
2634
|
-
}
|
2635
|
-
finally {
|
2636
|
-
span.end();
|
2637
|
-
}
|
2185
|
+
this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
|
2186
|
+
maxRetries: 0,
|
2187
|
+
} }));
|
2638
2188
|
}
|
2639
2189
|
/**
|
2640
2190
|
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
@@ -2645,133 +2195,92 @@ class LegacyMsiProvider {
|
|
2645
2195
|
* @param options - The options used to configure any requests this
|
2646
2196
|
* TokenCredential implementation might make.
|
2647
2197
|
*/
|
2648
|
-
async getToken(scopes, options) {
|
2649
|
-
|
2650
|
-
const
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2655
|
-
|
2656
|
-
const
|
2657
|
-
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2198
|
+
async getToken(scopes, options = {}) {
|
2199
|
+
logger$e.getToken.info("Using the MSAL provider for Managed Identity.");
|
2200
|
+
const resource = mapScopesToResource(scopes);
|
2201
|
+
if (!resource) {
|
2202
|
+
throw new CredentialUnavailableError(`ManagedIdentityCredential: Multiple scopes are not supported. Scopes: ${JSON.stringify(scopes)}`);
|
2203
|
+
}
|
2204
|
+
return tracingClient.withSpan("ManagedIdentityCredential.getToken", options, async () => {
|
2205
|
+
try {
|
2206
|
+
const isTokenExchangeMsi = await tokenExchangeMsi.isAvailable({
|
2207
|
+
scopes,
|
2208
|
+
clientId: this.clientId,
|
2209
|
+
getTokenOptions: options,
|
2210
|
+
identityClient: this.identityClient,
|
2211
|
+
resourceId: this.resourceId,
|
2212
|
+
});
|
2213
|
+
// Most scenarios are handled by MSAL except for two:
|
2214
|
+
// AKS pod identity - MSAL does not implement the token exchange flow.
|
2215
|
+
// IMDS Endpoint probing - MSAL does not do any probing before trying to get a token.
|
2216
|
+
// As a DefaultAzureCredential optimization we probe the IMDS endpoint with a short timeout and no retries before actually trying to get a token
|
2217
|
+
// We will continue to implement these features in the Identity library.
|
2218
|
+
const identitySource = this.managedIdentityApp.getManagedIdentitySource();
|
2219
|
+
const isImdsMsi = identitySource === "DefaultToImds" || identitySource === "Imds"; // Neither actually checks that IMDS endpoint is available, just that it's the source the MSAL _would_ try to use.
|
2220
|
+
if (isTokenExchangeMsi) {
|
2221
|
+
// In the AKS scenario we will use the existing tokenExchangeMsi indefinitely.
|
2222
|
+
logger$e.getToken.info("Using the token exchange managed identity.");
|
2223
|
+
const result = await tokenExchangeMsi.getToken({
|
2224
|
+
scopes,
|
2225
|
+
clientId: this.clientId,
|
2226
|
+
identityClient: this.identityClient,
|
2227
|
+
retryConfig: this.msiRetryConfig,
|
2228
|
+
resourceId: this.resourceId,
|
2229
|
+
});
|
2230
|
+
if (result === null) {
|
2231
|
+
throw new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
|
2232
|
+
}
|
2233
|
+
return result;
|
2671
2234
|
}
|
2672
|
-
if (
|
2673
|
-
//
|
2674
|
-
//
|
2675
|
-
|
2676
|
-
|
2677
|
-
|
2678
|
-
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2235
|
+
else if (isImdsMsi) {
|
2236
|
+
// In the IMDS scenario we will probe the IMDS endpoint to ensure it's available before trying to get a token.
|
2237
|
+
// If the IMDS endpoint is not available and this is the source that MSAL will use, we will fail-fast with an error that tells DAC to move to the next credential.
|
2238
|
+
logger$e.getToken.info("Using the IMDS endpoint to probe for availability.");
|
2239
|
+
const isAvailable = await imdsMsi.isAvailable({
|
2240
|
+
scopes,
|
2241
|
+
clientId: this.clientId,
|
2242
|
+
getTokenOptions: options,
|
2243
|
+
identityClient: this.isAvailableIdentityClient,
|
2244
|
+
resourceId: this.resourceId,
|
2245
|
+
});
|
2246
|
+
if (!isAvailable) {
|
2247
|
+
throw new CredentialUnavailableError(`ManagedIdentityCredential: The managed identity endpoint is not available.`);
|
2248
|
+
}
|
2682
2249
|
}
|
2683
|
-
//
|
2684
|
-
//
|
2685
|
-
//
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
logger$e.getToken.info(
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
}
|
2698
|
-
catch (err) {
|
2699
|
-
// CredentialUnavailable errors are expected to reach here.
|
2700
|
-
// We intend them to bubble up, so that DefaultAzureCredential can catch them.
|
2701
|
-
if (err.name === "AuthenticationRequiredError") {
|
2702
|
-
throw err;
|
2703
|
-
}
|
2704
|
-
// Expected errors to reach this point:
|
2705
|
-
// - Errors coming from a method unexpectedly breaking.
|
2706
|
-
// - When identityClient.sendTokenRequest throws, in which case
|
2707
|
-
// if the status code was 400, it means that the endpoint is working,
|
2708
|
-
// but no identity is available.
|
2709
|
-
span.setStatus({
|
2710
|
-
status: "error",
|
2711
|
-
error: err,
|
2712
|
-
});
|
2713
|
-
// If either the network is unreachable,
|
2714
|
-
// we can safely assume the credential is unavailable.
|
2715
|
-
if (err.code === "ENETUNREACH") {
|
2716
|
-
const error = new CredentialUnavailableError(`ManagedIdentityCredential: Unavailable. Network unreachable. Message: ${err.message}`);
|
2717
|
-
logger$e.getToken.info(formatError(scopes, error));
|
2718
|
-
throw error;
|
2719
|
-
}
|
2720
|
-
// If either the host was unreachable,
|
2721
|
-
// we can safely assume the credential is unavailable.
|
2722
|
-
if (err.code === "EHOSTUNREACH") {
|
2723
|
-
const error = new CredentialUnavailableError(`ManagedIdentityCredential: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
|
2724
|
-
logger$e.getToken.info(formatError(scopes, error));
|
2725
|
-
throw error;
|
2726
|
-
}
|
2727
|
-
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
2728
|
-
// and it means that the endpoint is working, but that no identity is available.
|
2729
|
-
if (err.statusCode === 400) {
|
2730
|
-
throw new CredentialUnavailableError(`ManagedIdentityCredential: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
|
2250
|
+
// If we got this far, it means:
|
2251
|
+
// - This is not a tokenExchangeMsi,
|
2252
|
+
// - We already probed for IMDS endpoint availability and failed-fast if it's unreachable.
|
2253
|
+
// We can proceed normally by calling MSAL for a token.
|
2254
|
+
logger$e.getToken.info("Calling into MSAL for managed identity token.");
|
2255
|
+
const token = await this.managedIdentityApp.acquireToken({
|
2256
|
+
resource,
|
2257
|
+
});
|
2258
|
+
this.ensureValidMsalToken(scopes, token, options);
|
2259
|
+
logger$e.getToken.info(formatSuccess(scopes));
|
2260
|
+
return {
|
2261
|
+
expiresOnTimestamp: token.expiresOn.getTime(),
|
2262
|
+
token: token.accessToken,
|
2263
|
+
};
|
2731
2264
|
}
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2265
|
+
catch (err) {
|
2266
|
+
logger$e.getToken.error(formatError(scopes, err));
|
2267
|
+
// AuthenticationRequiredError described as Error to enforce authentication after trying to retrieve a token silently.
|
2268
|
+
// TODO: why would this _ever_ happen considering we're not trying the silent request in this flow?
|
2269
|
+
if (err.name === "AuthenticationRequiredError") {
|
2270
|
+
throw err;
|
2271
|
+
}
|
2272
|
+
if (isNetworkError(err)) {
|
2273
|
+
throw new CredentialUnavailableError(`ManagedIdentityCredential: Network unreachable. Message: ${err.message}`);
|
2739
2274
|
}
|
2740
|
-
}
|
2741
|
-
// If the error has no status code, we can assume there was no available identity.
|
2742
|
-
// This will throw silently during any ChainedTokenCredential.
|
2743
|
-
if (err.statusCode === undefined) {
|
2744
2275
|
throw new CredentialUnavailableError(`ManagedIdentityCredential: Authentication failed. Message ${err.message}`);
|
2745
2276
|
}
|
2746
|
-
|
2747
|
-
throw new AuthenticationError(err.statusCode, {
|
2748
|
-
error: `ManagedIdentityCredential authentication failed.`,
|
2749
|
-
error_description: err.message,
|
2750
|
-
});
|
2751
|
-
}
|
2752
|
-
finally {
|
2753
|
-
// Finally is always called, both if we return and if we throw in the above try/catch.
|
2754
|
-
span.end();
|
2755
|
-
}
|
2756
|
-
}
|
2757
|
-
/**
|
2758
|
-
* Handles the MSAL authentication result.
|
2759
|
-
* If the result has an account, we update the local account reference.
|
2760
|
-
* If the token received is invalid, an error will be thrown depending on what's missing.
|
2761
|
-
*/
|
2762
|
-
handleResult(scopes, result, getTokenOptions) {
|
2763
|
-
this.ensureValidMsalToken(scopes, result, getTokenOptions);
|
2764
|
-
logger$e.getToken.info(formatSuccess(scopes));
|
2765
|
-
return {
|
2766
|
-
token: result.accessToken,
|
2767
|
-
expiresOnTimestamp: result.expiresOn.getTime(),
|
2768
|
-
};
|
2277
|
+
});
|
2769
2278
|
}
|
2770
2279
|
/**
|
2771
2280
|
* Ensures the validity of the MSAL token
|
2772
2281
|
*/
|
2773
2282
|
ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
|
2774
|
-
const
|
2283
|
+
const createError = (message) => {
|
2775
2284
|
logger$e.getToken.info(message);
|
2776
2285
|
return new AuthenticationRequiredError({
|
2777
2286
|
scopes: Array.isArray(scopes) ? scopes : [scopes],
|
@@ -2780,43 +2289,33 @@ class LegacyMsiProvider {
|
|
2780
2289
|
});
|
2781
2290
|
};
|
2782
2291
|
if (!msalToken) {
|
2783
|
-
throw
|
2292
|
+
throw createError("No response");
|
2784
2293
|
}
|
2785
2294
|
if (!msalToken.expiresOn) {
|
2786
|
-
throw
|
2295
|
+
throw createError(`Response had no "expiresOn" property.`);
|
2787
2296
|
}
|
2788
2297
|
if (!msalToken.accessToken) {
|
2789
|
-
throw
|
2298
|
+
throw createError(`Response had no "accessToken" property.`);
|
2790
2299
|
}
|
2791
2300
|
}
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
2802
|
-
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
|
2807
|
-
};
|
2808
|
-
}
|
2809
|
-
else {
|
2810
|
-
logger$e.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
|
2811
|
-
return {
|
2812
|
-
accessToken: "no_access_token_returned",
|
2813
|
-
expiresInSeconds: 0,
|
2814
|
-
};
|
2815
|
-
}
|
2816
|
-
});
|
2817
|
-
this.isAppTokenProviderInitialized = true;
|
2301
|
+
}
|
2302
|
+
function isNetworkError(err) {
|
2303
|
+
// MSAL error
|
2304
|
+
if (err.errorCode === "network_error") {
|
2305
|
+
return true;
|
2306
|
+
}
|
2307
|
+
// Probe errors
|
2308
|
+
if (err.code === "ENETUNREACH" || err.code === "EHOSTUNREACH") {
|
2309
|
+
return true;
|
2310
|
+
}
|
2311
|
+
// This is a special case for Docker Desktop which responds with a 403 with a message that contains "A socket operation was attempted to an unreachable network" or "A socket operation was attempted to an unreachable host"
|
2312
|
+
// rather than just timing out, as expected.
|
2313
|
+
if (err.statusCode === 403 || err.code === 403) {
|
2314
|
+
if (err.message.includes("unreachable")) {
|
2315
|
+
return true;
|
2818
2316
|
}
|
2819
2317
|
}
|
2318
|
+
return false;
|
2820
2319
|
}
|
2821
2320
|
|
2822
2321
|
// Copyright (c) Microsoft Corporation.
|
@@ -2835,7 +2334,11 @@ class ManagedIdentityCredential {
|
|
2835
2334
|
* @hidden
|
2836
2335
|
*/
|
2837
2336
|
constructor(clientIdOrOptions, options) {
|
2838
|
-
|
2337
|
+
// https://github.com/Azure/azure-sdk-for-js/issues/30189
|
2338
|
+
// If needed, you may release a hotfix to quickly rollback to the legacy implementation by changing the following line to:
|
2339
|
+
// this.implProvider = new LegacyMsiProvider(clientIdOrOptions, options);
|
2340
|
+
// Once stabilized, you can remove the legacy implementation and inline the msalMsiProvider code here as a drop-in replacement.
|
2341
|
+
this.implProvider = new MsalMsiProvider(clientIdOrOptions, options);
|
2839
2342
|
}
|
2840
2343
|
/**
|
2841
2344
|
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
@@ -3366,12 +2869,7 @@ class AzurePowerShellCredential {
|
|
3366
2869
|
],
|
3367
2870
|
]);
|
3368
2871
|
const result = results[1];
|
3369
|
-
|
3370
|
-
return JSON.parse(result);
|
3371
|
-
}
|
3372
|
-
catch (e) {
|
3373
|
-
throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`);
|
3374
|
-
}
|
2872
|
+
return parseJsonToken(result);
|
3375
2873
|
}
|
3376
2874
|
throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`);
|
3377
2875
|
}
|
@@ -3418,6 +2916,38 @@ class AzurePowerShellCredential {
|
|
3418
2916
|
});
|
3419
2917
|
}
|
3420
2918
|
}
|
2919
|
+
/**
|
2920
|
+
*
|
2921
|
+
* @internal
|
2922
|
+
*/
|
2923
|
+
async function parseJsonToken(result) {
|
2924
|
+
const jsonRegex = /{[^{}]*}/g;
|
2925
|
+
const matches = result.match(jsonRegex);
|
2926
|
+
let resultWithoutToken = result;
|
2927
|
+
if (matches) {
|
2928
|
+
try {
|
2929
|
+
for (const item of matches) {
|
2930
|
+
try {
|
2931
|
+
const jsonContent = JSON.parse(item);
|
2932
|
+
if (jsonContent === null || jsonContent === void 0 ? void 0 : jsonContent.Token) {
|
2933
|
+
resultWithoutToken = resultWithoutToken.replace(item, "");
|
2934
|
+
if (resultWithoutToken) {
|
2935
|
+
logger$b.getToken.warning(resultWithoutToken);
|
2936
|
+
}
|
2937
|
+
return jsonContent;
|
2938
|
+
}
|
2939
|
+
}
|
2940
|
+
catch (e) {
|
2941
|
+
continue;
|
2942
|
+
}
|
2943
|
+
}
|
2944
|
+
}
|
2945
|
+
catch (e) {
|
2946
|
+
throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`);
|
2947
|
+
}
|
2948
|
+
}
|
2949
|
+
throw new Error(`No access token found in the output. Received output: ${result}`);
|
2950
|
+
}
|
3421
2951
|
|
3422
2952
|
// Copyright (c) Microsoft Corporation.
|
3423
2953
|
// Licensed under the MIT license.
|
@@ -4200,30 +3730,45 @@ class AzurePipelinesCredential {
|
|
4200
3730
|
}),
|
4201
3731
|
});
|
4202
3732
|
const response = await this.identityClient.sendRequest(request);
|
4203
|
-
|
4204
|
-
|
4205
|
-
|
4206
|
-
|
3733
|
+
return handleOidcResponse(response);
|
3734
|
+
}
|
3735
|
+
}
|
3736
|
+
function handleOidcResponse(response) {
|
3737
|
+
const text = response.bodyAsText;
|
3738
|
+
if (!text) {
|
3739
|
+
logger$2.error(`${credentialName$1}: Authentication Failed. Received null token from OIDC request. Response status- ${response.status}. Complete response - ${JSON.stringify(response)}`);
|
3740
|
+
throw new AuthenticationError(response.status, {
|
3741
|
+
error: `${credentialName$1}: Authentication Failed. Received null token from OIDC request.`,
|
3742
|
+
error_description: `${JSON.stringify(response)}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
|
3743
|
+
});
|
3744
|
+
}
|
3745
|
+
try {
|
3746
|
+
const result = JSON.parse(text);
|
3747
|
+
if (result === null || result === void 0 ? void 0 : result.oidcToken) {
|
3748
|
+
return result.oidcToken;
|
4207
3749
|
}
|
4208
|
-
|
4209
|
-
const
|
4210
|
-
|
4211
|
-
|
4212
|
-
|
4213
|
-
else {
|
4214
|
-
let errorMessage = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
4215
|
-
if (response.status !== 200) {
|
4216
|
-
errorMessage += `Response = ${JSON.stringify(result)}`;
|
4217
|
-
}
|
4218
|
-
logger$2.error(errorMessage);
|
4219
|
-
throw new AuthenticationError(response.status, errorMessage);
|
3750
|
+
else {
|
3751
|
+
const errorMessage = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
3752
|
+
let errorDescription = ``;
|
3753
|
+
if (response.status !== 200) {
|
3754
|
+
errorDescription = `Complete response - ${JSON.stringify(result)}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`;
|
4220
3755
|
}
|
3756
|
+
logger$2.error(errorMessage);
|
3757
|
+
logger$2.error(errorDescription);
|
3758
|
+
throw new AuthenticationError(response.status, {
|
3759
|
+
error: errorMessage,
|
3760
|
+
error_description: errorDescription,
|
3761
|
+
});
|
4221
3762
|
}
|
4222
|
-
|
4223
|
-
|
4224
|
-
|
4225
|
-
|
4226
|
-
|
3763
|
+
}
|
3764
|
+
catch (e) {
|
3765
|
+
const errorDetails = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
3766
|
+
logger$2.error(`Response from service = ${text} and error message = ${e.message}`);
|
3767
|
+
logger$2.error(errorDetails);
|
3768
|
+
throw new AuthenticationError(response.status, {
|
3769
|
+
error: errorDetails,
|
3770
|
+
error_description: `Response = ${text}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
|
3771
|
+
});
|
4227
3772
|
}
|
4228
3773
|
}
|
4229
3774
|
|
@@ -4467,7 +4012,7 @@ exports.WorkloadIdentityCredential = WorkloadIdentityCredential;
|
|
4467
4012
|
exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord;
|
4468
4013
|
exports.getBearerTokenProvider = getBearerTokenProvider;
|
4469
4014
|
exports.getDefaultAzureCredential = getDefaultAzureCredential;
|
4470
|
-
exports.logger = logger$
|
4015
|
+
exports.logger = logger$l;
|
4471
4016
|
exports.serializeAuthenticationRecord = serializeAuthenticationRecord;
|
4472
4017
|
exports.useIdentityPlugin = useIdentityPlugin;
|
4473
4018
|
//# sourceMappingURL=index.js.map
|