@azure/identity 4.1.0-alpha.20240328.2 → 4.1.0-alpha.20240409.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/dist/index.js +396 -389
- package/dist/index.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js +9 -5
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +10 -16
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +22 -13
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
- package/package.json +2 -2
- package/types/identity.d.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -12,8 +12,8 @@ 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 promises = require('fs/promises');
|
|
16
15
|
var https = require('https');
|
|
16
|
+
var promises = require('fs/promises');
|
|
17
17
|
var child_process = require('child_process');
|
|
18
18
|
var crypto = require('crypto');
|
|
19
19
|
var util = require('util');
|
|
@@ -1022,7 +1022,7 @@ const appServiceMsi2017 = {
|
|
|
1022
1022
|
|
|
1023
1023
|
// Copyright (c) Microsoft Corporation.
|
|
1024
1024
|
// Licensed under the MIT license.
|
|
1025
|
-
const msiName$5 = "ManagedIdentityCredential -
|
|
1025
|
+
const msiName$5 = "ManagedIdentityCredential - AppServiceMSI 2019";
|
|
1026
1026
|
const logger$m = credentialLogger(msiName$5);
|
|
1027
1027
|
/**
|
|
1028
1028
|
* Generates the options used on the request for an access token.
|
|
@@ -1032,58 +1032,54 @@ function prepareRequestOptions$4(scopes, clientId, resourceId) {
|
|
|
1032
1032
|
if (!resource) {
|
|
1033
1033
|
throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
|
|
1034
1034
|
}
|
|
1035
|
-
const
|
|
1035
|
+
const queryParameters = {
|
|
1036
1036
|
resource,
|
|
1037
|
+
"api-version": "2019-08-01",
|
|
1037
1038
|
};
|
|
1038
1039
|
if (clientId) {
|
|
1039
|
-
|
|
1040
|
+
queryParameters.client_id = clientId;
|
|
1040
1041
|
}
|
|
1041
1042
|
if (resourceId) {
|
|
1042
|
-
|
|
1043
|
+
queryParameters.mi_res_id = resourceId;
|
|
1043
1044
|
}
|
|
1045
|
+
const query = new URLSearchParams(queryParameters);
|
|
1044
1046
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
1045
|
-
if (!process.env.
|
|
1046
|
-
throw new Error(`${msiName$5}: Missing environment variable:
|
|
1047
|
+
if (!process.env.IDENTITY_ENDPOINT) {
|
|
1048
|
+
throw new Error(`${msiName$5}: Missing environment variable: IDENTITY_ENDPOINT`);
|
|
1049
|
+
}
|
|
1050
|
+
if (!process.env.IDENTITY_HEADER) {
|
|
1051
|
+
throw new Error(`${msiName$5}: Missing environment variable: IDENTITY_HEADER`);
|
|
1047
1052
|
}
|
|
1048
|
-
const params = new URLSearchParams(body);
|
|
1049
1053
|
return {
|
|
1050
|
-
url: process.env.
|
|
1051
|
-
method: "
|
|
1052
|
-
body: params.toString(),
|
|
1054
|
+
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
|
1055
|
+
method: "GET",
|
|
1053
1056
|
headers: coreRestPipeline.createHttpHeaders({
|
|
1054
1057
|
Accept: "application/json",
|
|
1055
|
-
|
|
1056
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
1058
|
+
"X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
|
|
1057
1059
|
}),
|
|
1058
1060
|
};
|
|
1059
1061
|
}
|
|
1060
1062
|
/**
|
|
1061
|
-
* Defines how to determine whether the Azure
|
|
1062
|
-
* 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.
|
|
1063
|
+
* 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.
|
|
1063
1064
|
*/
|
|
1064
|
-
const
|
|
1065
|
-
name: "
|
|
1065
|
+
const appServiceMsi2019 = {
|
|
1066
|
+
name: "appServiceMsi2019",
|
|
1066
1067
|
async isAvailable({ scopes }) {
|
|
1067
1068
|
const resource = mapScopesToResource(scopes);
|
|
1068
1069
|
if (!resource) {
|
|
1069
1070
|
logger$m.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
|
|
1070
1071
|
return false;
|
|
1071
1072
|
}
|
|
1072
|
-
const
|
|
1073
|
+
const env = process.env;
|
|
1074
|
+
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
|
|
1073
1075
|
if (!result) {
|
|
1074
|
-
logger$m.info(`${msiName$5}: Unavailable. The environment
|
|
1076
|
+
logger$m.info(`${msiName$5}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
|
|
1075
1077
|
}
|
|
1076
1078
|
return result;
|
|
1077
1079
|
},
|
|
1078
1080
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1079
1081
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1080
|
-
|
|
1081
|
-
logger$m.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
1082
|
-
}
|
|
1083
|
-
if (resourceId) {
|
|
1084
|
-
logger$m.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
|
1085
|
-
}
|
|
1086
|
-
logger$m.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
1082
|
+
logger$m.info(`${msiName$5}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
|
1087
1083
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
|
|
1088
1084
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1089
1085
|
allowInsecureConnection: true }));
|
|
@@ -1094,159 +1090,16 @@ const cloudShellMsi = {
|
|
|
1094
1090
|
|
|
1095
1091
|
// Copyright (c) Microsoft Corporation.
|
|
1096
1092
|
// Licensed under the MIT license.
|
|
1097
|
-
const msiName$4 = "ManagedIdentityCredential -
|
|
1093
|
+
const msiName$4 = "ManagedIdentityCredential - Azure Arc MSI";
|
|
1098
1094
|
const logger$l = credentialLogger(msiName$4);
|
|
1099
1095
|
/**
|
|
1100
1096
|
* Generates the options used on the request for an access token.
|
|
1101
1097
|
*/
|
|
1102
|
-
function prepareRequestOptions$3(scopes, clientId, resourceId
|
|
1103
|
-
var _a;
|
|
1098
|
+
function prepareRequestOptions$3(scopes, clientId, resourceId) {
|
|
1104
1099
|
const resource = mapScopesToResource(scopes);
|
|
1105
1100
|
if (!resource) {
|
|
1106
1101
|
throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
|
|
1107
1102
|
}
|
|
1108
|
-
const { skipQuery, skipMetadataHeader } = options || {};
|
|
1109
|
-
let query = "";
|
|
1110
|
-
// Pod Identity will try to process this request even if the Metadata header is missing.
|
|
1111
|
-
// We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
|
|
1112
|
-
if (!skipQuery) {
|
|
1113
|
-
const queryParameters = {
|
|
1114
|
-
resource,
|
|
1115
|
-
"api-version": imdsApiVersion,
|
|
1116
|
-
};
|
|
1117
|
-
if (clientId) {
|
|
1118
|
-
queryParameters.client_id = clientId;
|
|
1119
|
-
}
|
|
1120
|
-
if (resourceId) {
|
|
1121
|
-
queryParameters.msi_res_id = resourceId;
|
|
1122
|
-
}
|
|
1123
|
-
const params = new URLSearchParams(queryParameters);
|
|
1124
|
-
query = `?${params.toString()}`;
|
|
1125
|
-
}
|
|
1126
|
-
const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
|
|
1127
|
-
const rawHeaders = {
|
|
1128
|
-
Accept: "application/json",
|
|
1129
|
-
Metadata: "true",
|
|
1130
|
-
};
|
|
1131
|
-
// Remove the Metadata header to invoke a request error from some IMDS endpoints.
|
|
1132
|
-
if (skipMetadataHeader) {
|
|
1133
|
-
delete rawHeaders.Metadata;
|
|
1134
|
-
}
|
|
1135
|
-
return {
|
|
1136
|
-
// In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
|
|
1137
|
-
url: `${url}${query}`,
|
|
1138
|
-
method: "GET",
|
|
1139
|
-
headers: coreRestPipeline.createHttpHeaders(rawHeaders),
|
|
1140
|
-
};
|
|
1141
|
-
}
|
|
1142
|
-
// 800ms -> 1600ms -> 3200ms
|
|
1143
|
-
const imdsMsiRetryConfig = {
|
|
1144
|
-
maxRetries: 3,
|
|
1145
|
-
startDelayInMs: 800,
|
|
1146
|
-
intervalIncrement: 2,
|
|
1147
|
-
};
|
|
1148
|
-
/**
|
|
1149
|
-
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
1150
|
-
*/
|
|
1151
|
-
const imdsMsi = {
|
|
1152
|
-
name: "imdsMsi",
|
|
1153
|
-
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
|
|
1154
|
-
const resource = mapScopesToResource(scopes);
|
|
1155
|
-
if (!resource) {
|
|
1156
|
-
logger$l.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
|
|
1157
|
-
return false;
|
|
1158
|
-
}
|
|
1159
|
-
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
|
|
1160
|
-
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
1161
|
-
return true;
|
|
1162
|
-
}
|
|
1163
|
-
if (!identityClient) {
|
|
1164
|
-
throw new Error("Missing IdentityClient");
|
|
1165
|
-
}
|
|
1166
|
-
const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
|
|
1167
|
-
skipMetadataHeader: true,
|
|
1168
|
-
skipQuery: true,
|
|
1169
|
-
});
|
|
1170
|
-
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
|
|
1171
|
-
var _a, _b;
|
|
1172
|
-
requestOptions.tracingOptions = options.tracingOptions;
|
|
1173
|
-
// Create a request with a timeout since we expect that
|
|
1174
|
-
// not having a "Metadata" header should cause an error to be
|
|
1175
|
-
// returned quickly from the endpoint, proving its availability.
|
|
1176
|
-
const request = coreRestPipeline.createPipelineRequest(requestOptions);
|
|
1177
|
-
// Default to 1000 if the default of 0 is used.
|
|
1178
|
-
// Negative values can still be used to disable the timeout.
|
|
1179
|
-
request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
|
|
1180
|
-
// This MSI uses the imdsEndpoint to get the token, which only uses http://
|
|
1181
|
-
request.allowInsecureConnection = true;
|
|
1182
|
-
let response;
|
|
1183
|
-
try {
|
|
1184
|
-
logger$l.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
|
|
1185
|
-
response = await identityClient.sendRequest(request);
|
|
1186
|
-
}
|
|
1187
|
-
catch (err) {
|
|
1188
|
-
// If the request failed, or Node.js was unable to establish a connection,
|
|
1189
|
-
// or the host was down, we'll assume the IMDS endpoint isn't available.
|
|
1190
|
-
if (coreUtil.isError(err)) {
|
|
1191
|
-
logger$l.verbose(`${msiName$4}: Caught error ${err.name}: ${err.message}`);
|
|
1192
|
-
}
|
|
1193
|
-
// 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"
|
|
1194
|
-
// rather than just timing out, as expected.
|
|
1195
|
-
logger$l.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
|
|
1196
|
-
return false;
|
|
1197
|
-
}
|
|
1198
|
-
if (response.status === 403) {
|
|
1199
|
-
if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("A socket operation was attempted to an unreachable network")) {
|
|
1200
|
-
logger$l.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
|
|
1201
|
-
logger$l.info(`${msiName$4}: ${response.bodyAsText}`);
|
|
1202
|
-
return false;
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
// If we received any response, the endpoint is available
|
|
1206
|
-
logger$l.info(`${msiName$4}: The Azure IMDS endpoint is available`);
|
|
1207
|
-
return true;
|
|
1208
|
-
});
|
|
1209
|
-
},
|
|
1210
|
-
async getToken(configuration, getTokenOptions = {}) {
|
|
1211
|
-
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1212
|
-
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
1213
|
-
logger$l.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
|
|
1214
|
-
}
|
|
1215
|
-
else {
|
|
1216
|
-
logger$l.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
|
|
1217
|
-
}
|
|
1218
|
-
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
|
|
1219
|
-
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
|
|
1220
|
-
try {
|
|
1221
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
|
|
1222
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1223
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1224
|
-
}
|
|
1225
|
-
catch (error) {
|
|
1226
|
-
if (error.statusCode === 404) {
|
|
1227
|
-
await coreUtil.delay(nextDelayInMs);
|
|
1228
|
-
nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
|
|
1229
|
-
continue;
|
|
1230
|
-
}
|
|
1231
|
-
throw error;
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
throw new AuthenticationError(404, `${msiName$4}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
|
|
1235
|
-
},
|
|
1236
|
-
};
|
|
1237
|
-
|
|
1238
|
-
// Copyright (c) Microsoft Corporation.
|
|
1239
|
-
// Licensed under the MIT license.
|
|
1240
|
-
const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
|
|
1241
|
-
const logger$k = credentialLogger(msiName$3);
|
|
1242
|
-
/**
|
|
1243
|
-
* Generates the options used on the request for an access token.
|
|
1244
|
-
*/
|
|
1245
|
-
function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
1246
|
-
const resource = mapScopesToResource(scopes);
|
|
1247
|
-
if (!resource) {
|
|
1248
|
-
throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
|
|
1249
|
-
}
|
|
1250
1103
|
const queryParameters = {
|
|
1251
1104
|
resource,
|
|
1252
1105
|
"api-version": azureArcAPIVersion,
|
|
@@ -1259,7 +1112,7 @@ function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
|
1259
1112
|
}
|
|
1260
1113
|
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
1261
1114
|
if (!process.env.IDENTITY_ENDPOINT) {
|
|
1262
|
-
throw new Error(`${msiName$
|
|
1115
|
+
throw new Error(`${msiName$4}: Missing environment variable: IDENTITY_ENDPOINT`);
|
|
1263
1116
|
}
|
|
1264
1117
|
const query = new URLSearchParams(queryParameters);
|
|
1265
1118
|
return coreRestPipeline.createPipelineRequest({
|
|
@@ -1294,7 +1147,7 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
1294
1147
|
if (response.bodyAsText) {
|
|
1295
1148
|
message = ` Response: ${response.bodyAsText}`;
|
|
1296
1149
|
}
|
|
1297
|
-
throw new AuthenticationError(response.status, `${msiName$
|
|
1150
|
+
throw new AuthenticationError(response.status, `${msiName$4}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
|
|
1298
1151
|
}
|
|
1299
1152
|
const authHeader = response.headers.get("www-authenticate") || "";
|
|
1300
1153
|
try {
|
|
@@ -1312,12 +1165,12 @@ const arcMsi = {
|
|
|
1312
1165
|
async isAvailable({ scopes }) {
|
|
1313
1166
|
const resource = mapScopesToResource(scopes);
|
|
1314
1167
|
if (!resource) {
|
|
1315
|
-
logger$
|
|
1168
|
+
logger$l.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
|
|
1316
1169
|
return false;
|
|
1317
1170
|
}
|
|
1318
1171
|
const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
|
|
1319
1172
|
if (!result) {
|
|
1320
|
-
logger$
|
|
1173
|
+
logger$l.info(`${msiName$4}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
|
|
1321
1174
|
}
|
|
1322
1175
|
return result;
|
|
1323
1176
|
},
|
|
@@ -1325,16 +1178,16 @@ const arcMsi = {
|
|
|
1325
1178
|
var _a;
|
|
1326
1179
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1327
1180
|
if (clientId) {
|
|
1328
|
-
logger$
|
|
1181
|
+
logger$l.warning(`${msiName$4}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
1329
1182
|
}
|
|
1330
1183
|
if (resourceId) {
|
|
1331
|
-
logger$
|
|
1184
|
+
logger$l.warning(`${msiName$4}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
|
|
1332
1185
|
}
|
|
1333
|
-
logger$
|
|
1334
|
-
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1186
|
+
logger$l.info(`${msiName$4}: Authenticating.`);
|
|
1187
|
+
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
|
1335
1188
|
const filePath = await filePathRequest(identityClient, requestOptions);
|
|
1336
1189
|
if (!filePath) {
|
|
1337
|
-
throw new Error(`${msiName$
|
|
1190
|
+
throw new Error(`${msiName$4}: Failed to find the token file.`);
|
|
1338
1191
|
}
|
|
1339
1192
|
const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
|
|
1340
1193
|
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
|
@@ -1346,12 +1199,174 @@ const arcMsi = {
|
|
|
1346
1199
|
},
|
|
1347
1200
|
};
|
|
1348
1201
|
|
|
1202
|
+
// Copyright (c) Microsoft Corporation.
|
|
1203
|
+
// Licensed under the MIT license.
|
|
1204
|
+
const msiName$3 = "ManagedIdentityCredential - CloudShellMSI";
|
|
1205
|
+
const logger$k = credentialLogger(msiName$3);
|
|
1206
|
+
/**
|
|
1207
|
+
* Generates the options used on the request for an access token.
|
|
1208
|
+
*/
|
|
1209
|
+
function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
1210
|
+
const resource = mapScopesToResource(scopes);
|
|
1211
|
+
if (!resource) {
|
|
1212
|
+
throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
|
|
1213
|
+
}
|
|
1214
|
+
const body = {
|
|
1215
|
+
resource,
|
|
1216
|
+
};
|
|
1217
|
+
if (clientId) {
|
|
1218
|
+
body.client_id = clientId;
|
|
1219
|
+
}
|
|
1220
|
+
if (resourceId) {
|
|
1221
|
+
body.msi_res_id = resourceId;
|
|
1222
|
+
}
|
|
1223
|
+
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
1224
|
+
if (!process.env.MSI_ENDPOINT) {
|
|
1225
|
+
throw new Error(`${msiName$3}: Missing environment variable: MSI_ENDPOINT`);
|
|
1226
|
+
}
|
|
1227
|
+
const params = new URLSearchParams(body);
|
|
1228
|
+
return {
|
|
1229
|
+
url: process.env.MSI_ENDPOINT,
|
|
1230
|
+
method: "POST",
|
|
1231
|
+
body: params.toString(),
|
|
1232
|
+
headers: coreRestPipeline.createHttpHeaders({
|
|
1233
|
+
Accept: "application/json",
|
|
1234
|
+
Metadata: "true",
|
|
1235
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1236
|
+
}),
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* 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.
|
|
1241
|
+
* 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.
|
|
1242
|
+
*/
|
|
1243
|
+
const cloudShellMsi = {
|
|
1244
|
+
name: "cloudShellMsi",
|
|
1245
|
+
async isAvailable({ scopes }) {
|
|
1246
|
+
const resource = mapScopesToResource(scopes);
|
|
1247
|
+
if (!resource) {
|
|
1248
|
+
logger$k.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
|
|
1249
|
+
return false;
|
|
1250
|
+
}
|
|
1251
|
+
const result = Boolean(process.env.MSI_ENDPOINT);
|
|
1252
|
+
if (!result) {
|
|
1253
|
+
logger$k.info(`${msiName$3}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
|
|
1254
|
+
}
|
|
1255
|
+
return result;
|
|
1256
|
+
},
|
|
1257
|
+
async getToken(configuration, getTokenOptions = {}) {
|
|
1258
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1259
|
+
if (clientId) {
|
|
1260
|
+
logger$k.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
|
|
1261
|
+
}
|
|
1262
|
+
if (resourceId) {
|
|
1263
|
+
logger$k.warning(`${msiName$3}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
|
1264
|
+
}
|
|
1265
|
+
logger$k.info(`${msiName$3}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
1266
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), {
|
|
1267
|
+
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1268
|
+
allowInsecureConnection: true }));
|
|
1269
|
+
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1270
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1271
|
+
},
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
// Copyright (c) Microsoft Corporation.
|
|
1275
|
+
// Licensed under the MIT license.
|
|
1276
|
+
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
|
|
1277
|
+
//
|
|
1278
|
+
// FROM node:12
|
|
1279
|
+
// RUN wget https://host.any/path/bash.sh
|
|
1280
|
+
// CMD ["bash", "bash.sh"]
|
|
1281
|
+
//
|
|
1282
|
+
// Where the bash script contains:
|
|
1283
|
+
//
|
|
1284
|
+
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
1285
|
+
//
|
|
1286
|
+
const msiName$2 = "ManagedIdentityCredential - Fabric MSI";
|
|
1287
|
+
const logger$j = credentialLogger(msiName$2);
|
|
1288
|
+
/**
|
|
1289
|
+
* Generates the options used on the request for an access token.
|
|
1290
|
+
*/
|
|
1291
|
+
function prepareRequestOptions$1(scopes, clientId, resourceId) {
|
|
1292
|
+
const resource = mapScopesToResource(scopes);
|
|
1293
|
+
if (!resource) {
|
|
1294
|
+
throw new Error(`${msiName$2}: Multiple scopes are not supported.`);
|
|
1295
|
+
}
|
|
1296
|
+
const queryParameters = {
|
|
1297
|
+
resource,
|
|
1298
|
+
"api-version": azureFabricVersion,
|
|
1299
|
+
};
|
|
1300
|
+
if (clientId) {
|
|
1301
|
+
queryParameters.client_id = clientId;
|
|
1302
|
+
}
|
|
1303
|
+
if (resourceId) {
|
|
1304
|
+
queryParameters.msi_res_id = resourceId;
|
|
1305
|
+
}
|
|
1306
|
+
const query = new URLSearchParams(queryParameters);
|
|
1307
|
+
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
1308
|
+
if (!process.env.IDENTITY_ENDPOINT) {
|
|
1309
|
+
throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
|
|
1310
|
+
}
|
|
1311
|
+
if (!process.env.IDENTITY_HEADER) {
|
|
1312
|
+
throw new Error("Missing environment variable: IDENTITY_HEADER");
|
|
1313
|
+
}
|
|
1314
|
+
return {
|
|
1315
|
+
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
|
1316
|
+
method: "GET",
|
|
1317
|
+
headers: coreRestPipeline.createHttpHeaders({
|
|
1318
|
+
Accept: "application/json",
|
|
1319
|
+
secret: process.env.IDENTITY_HEADER,
|
|
1320
|
+
}),
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* 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.
|
|
1325
|
+
*/
|
|
1326
|
+
const fabricMsi = {
|
|
1327
|
+
name: "fabricMsi",
|
|
1328
|
+
async isAvailable({ scopes }) {
|
|
1329
|
+
const resource = mapScopesToResource(scopes);
|
|
1330
|
+
if (!resource) {
|
|
1331
|
+
logger$j.info(`${msiName$2}: Unavailable. Multiple scopes are not supported.`);
|
|
1332
|
+
return false;
|
|
1333
|
+
}
|
|
1334
|
+
const env = process.env;
|
|
1335
|
+
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
|
|
1336
|
+
if (!result) {
|
|
1337
|
+
logger$j.info(`${msiName$2}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
|
|
1338
|
+
}
|
|
1339
|
+
return result;
|
|
1340
|
+
},
|
|
1341
|
+
async getToken(configuration, getTokenOptions = {}) {
|
|
1342
|
+
const { scopes, identityClient, clientId, resourceId } = configuration;
|
|
1343
|
+
if (resourceId) {
|
|
1344
|
+
logger$j.warning(`${msiName$2}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
1345
|
+
}
|
|
1346
|
+
logger$j.info([
|
|
1347
|
+
`${msiName$2}:`,
|
|
1348
|
+
"Using the endpoint and the secret coming from the environment variables:",
|
|
1349
|
+
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
|
|
1350
|
+
"IDENTITY_HEADER=[REDACTED] and",
|
|
1351
|
+
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
|
|
1352
|
+
].join(" "));
|
|
1353
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
|
|
1354
|
+
request.agent = new https.Agent({
|
|
1355
|
+
// This is necessary because Service Fabric provides a self-signed certificate.
|
|
1356
|
+
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
|
1357
|
+
rejectUnauthorized: false,
|
|
1358
|
+
});
|
|
1359
|
+
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1360
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1361
|
+
},
|
|
1362
|
+
};
|
|
1363
|
+
|
|
1349
1364
|
// Copyright (c) Microsoft Corporation.
|
|
1350
1365
|
// Licensed under the MIT license.
|
|
1351
1366
|
/**
|
|
1352
1367
|
* @internal
|
|
1353
1368
|
*/
|
|
1354
|
-
const logger$
|
|
1369
|
+
const logger$i = credentialLogger("IdentityUtils");
|
|
1355
1370
|
/**
|
|
1356
1371
|
* Latest AuthenticationRecord version
|
|
1357
1372
|
* @internal
|
|
@@ -1363,7 +1378,7 @@ const LatestAuthenticationRecordVersion = "1.0";
|
|
|
1363
1378
|
*/
|
|
1364
1379
|
function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
|
|
1365
1380
|
const error = (message) => {
|
|
1366
|
-
logger$
|
|
1381
|
+
logger$i.getToken.info(message);
|
|
1367
1382
|
return new AuthenticationRequiredError({
|
|
1368
1383
|
scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
1369
1384
|
getTokenOptions,
|
|
@@ -1473,17 +1488,17 @@ function handleMsalError(scopes, error, getTokenOptions) {
|
|
|
1473
1488
|
const msalError = error;
|
|
1474
1489
|
switch (msalError.errorCode) {
|
|
1475
1490
|
case "endpoints_resolution_error":
|
|
1476
|
-
logger$
|
|
1491
|
+
logger$i.info(formatError(scopes, error.message));
|
|
1477
1492
|
return new CredentialUnavailableError(error.message);
|
|
1478
1493
|
case "device_code_polling_cancelled":
|
|
1479
1494
|
return new abortController.AbortError("The authentication has been aborted by the caller.");
|
|
1480
1495
|
case "consent_required":
|
|
1481
1496
|
case "interaction_required":
|
|
1482
1497
|
case "login_required":
|
|
1483
|
-
logger$
|
|
1498
|
+
logger$i.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
|
|
1484
1499
|
break;
|
|
1485
1500
|
default:
|
|
1486
|
-
logger$
|
|
1501
|
+
logger$i.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
|
|
1487
1502
|
break;
|
|
1488
1503
|
}
|
|
1489
1504
|
}
|
|
@@ -1493,7 +1508,7 @@ function handleMsalError(scopes, error, getTokenOptions) {
|
|
|
1493
1508
|
return error;
|
|
1494
1509
|
}
|
|
1495
1510
|
if (error.name === "NativeAuthError") {
|
|
1496
|
-
logger$
|
|
1511
|
+
logger$i.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
|
|
1497
1512
|
return error;
|
|
1498
1513
|
}
|
|
1499
1514
|
return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
|
|
@@ -1532,31 +1547,168 @@ function serializeAuthenticationRecord(record) {
|
|
|
1532
1547
|
return JSON.stringify(record);
|
|
1533
1548
|
}
|
|
1534
1549
|
/**
|
|
1535
|
-
* Deserializes a previously serialized authentication record from a string into an object.
|
|
1536
|
-
*
|
|
1537
|
-
* The input string must contain the following properties:
|
|
1538
|
-
*
|
|
1539
|
-
* - "authority"
|
|
1540
|
-
* - "homeAccountId"
|
|
1541
|
-
* - "clientId"
|
|
1542
|
-
* - "tenantId"
|
|
1543
|
-
* - "username"
|
|
1544
|
-
* - "version"
|
|
1545
|
-
*
|
|
1546
|
-
* If the version we receive is unsupported, an error will be thrown.
|
|
1547
|
-
*
|
|
1548
|
-
* At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
|
|
1549
|
-
*
|
|
1550
|
-
* @param serializedRecord - Authentication record previously serialized into string.
|
|
1551
|
-
* @returns AuthenticationRecord.
|
|
1550
|
+
* Deserializes a previously serialized authentication record from a string into an object.
|
|
1551
|
+
*
|
|
1552
|
+
* The input string must contain the following properties:
|
|
1553
|
+
*
|
|
1554
|
+
* - "authority"
|
|
1555
|
+
* - "homeAccountId"
|
|
1556
|
+
* - "clientId"
|
|
1557
|
+
* - "tenantId"
|
|
1558
|
+
* - "username"
|
|
1559
|
+
* - "version"
|
|
1560
|
+
*
|
|
1561
|
+
* If the version we receive is unsupported, an error will be thrown.
|
|
1562
|
+
*
|
|
1563
|
+
* At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
|
|
1564
|
+
*
|
|
1565
|
+
* @param serializedRecord - Authentication record previously serialized into string.
|
|
1566
|
+
* @returns AuthenticationRecord.
|
|
1567
|
+
*/
|
|
1568
|
+
function deserializeAuthenticationRecord(serializedRecord) {
|
|
1569
|
+
const parsed = JSON.parse(serializedRecord);
|
|
1570
|
+
if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
|
|
1571
|
+
throw Error("Unsupported AuthenticationRecord version");
|
|
1572
|
+
}
|
|
1573
|
+
return parsed;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// Copyright (c) Microsoft Corporation.
|
|
1577
|
+
// Licensed under the MIT license.
|
|
1578
|
+
const msiName$1 = "ManagedIdentityCredential - IMDS";
|
|
1579
|
+
const logger$h = credentialLogger(msiName$1);
|
|
1580
|
+
/**
|
|
1581
|
+
* Generates the options used on the request for an access token.
|
|
1582
|
+
*/
|
|
1583
|
+
function prepareRequestOptions(scopes, clientId, resourceId, options) {
|
|
1584
|
+
var _a;
|
|
1585
|
+
const resource = mapScopesToResource(scopes);
|
|
1586
|
+
if (!resource) {
|
|
1587
|
+
throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
|
|
1588
|
+
}
|
|
1589
|
+
const { skipQuery, skipMetadataHeader } = options || {};
|
|
1590
|
+
let query = "";
|
|
1591
|
+
// Pod Identity will try to process this request even if the Metadata header is missing.
|
|
1592
|
+
// We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
|
|
1593
|
+
if (!skipQuery) {
|
|
1594
|
+
const queryParameters = {
|
|
1595
|
+
resource,
|
|
1596
|
+
"api-version": imdsApiVersion,
|
|
1597
|
+
};
|
|
1598
|
+
if (clientId) {
|
|
1599
|
+
queryParameters.client_id = clientId;
|
|
1600
|
+
}
|
|
1601
|
+
if (resourceId) {
|
|
1602
|
+
queryParameters.msi_res_id = resourceId;
|
|
1603
|
+
}
|
|
1604
|
+
const params = new URLSearchParams(queryParameters);
|
|
1605
|
+
query = `?${params.toString()}`;
|
|
1606
|
+
}
|
|
1607
|
+
const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
|
|
1608
|
+
const rawHeaders = {
|
|
1609
|
+
Accept: "application/json",
|
|
1610
|
+
Metadata: "true",
|
|
1611
|
+
};
|
|
1612
|
+
// Remove the Metadata header to invoke a request error from some IMDS endpoints.
|
|
1613
|
+
if (skipMetadataHeader) {
|
|
1614
|
+
delete rawHeaders.Metadata;
|
|
1615
|
+
}
|
|
1616
|
+
return {
|
|
1617
|
+
// In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
|
|
1618
|
+
url: `${url}${query}`,
|
|
1619
|
+
method: "GET",
|
|
1620
|
+
headers: coreRestPipeline.createHttpHeaders(rawHeaders),
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
1552
1625
|
*/
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1626
|
+
const imdsMsi = {
|
|
1627
|
+
name: "imdsMsi",
|
|
1628
|
+
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
|
|
1629
|
+
const resource = mapScopesToResource(scopes);
|
|
1630
|
+
if (!resource) {
|
|
1631
|
+
logger$h.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
|
|
1632
|
+
return false;
|
|
1633
|
+
}
|
|
1634
|
+
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
|
|
1635
|
+
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
1636
|
+
return true;
|
|
1637
|
+
}
|
|
1638
|
+
if (!identityClient) {
|
|
1639
|
+
throw new Error("Missing IdentityClient");
|
|
1640
|
+
}
|
|
1641
|
+
const requestOptions = prepareRequestOptions(resource, clientId, resourceId, {
|
|
1642
|
+
skipMetadataHeader: true,
|
|
1643
|
+
skipQuery: true,
|
|
1644
|
+
});
|
|
1645
|
+
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
|
|
1646
|
+
var _a, _b;
|
|
1647
|
+
requestOptions.tracingOptions = options.tracingOptions;
|
|
1648
|
+
// Create a request with a timeout since we expect that
|
|
1649
|
+
// not having a "Metadata" header should cause an error to be
|
|
1650
|
+
// returned quickly from the endpoint, proving its availability.
|
|
1651
|
+
const request = coreRestPipeline.createPipelineRequest(requestOptions);
|
|
1652
|
+
// Default to 1000 if the default of 0 is used.
|
|
1653
|
+
// Negative values can still be used to disable the timeout.
|
|
1654
|
+
request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
|
|
1655
|
+
// This MSI uses the imdsEndpoint to get the token, which only uses http://
|
|
1656
|
+
request.allowInsecureConnection = true;
|
|
1657
|
+
let response;
|
|
1658
|
+
try {
|
|
1659
|
+
logger$h.info(`${msiName$1}: Pinging the Azure IMDS endpoint`);
|
|
1660
|
+
response = await identityClient.sendRequest(request);
|
|
1661
|
+
}
|
|
1662
|
+
catch (err) {
|
|
1663
|
+
// If the request failed, or Node.js was unable to establish a connection,
|
|
1664
|
+
// or the host was down, we'll assume the IMDS endpoint isn't available.
|
|
1665
|
+
if (coreUtil.isError(err)) {
|
|
1666
|
+
logger$h.verbose(`${msiName$1}: Caught error ${err.name}: ${err.message}`);
|
|
1667
|
+
}
|
|
1668
|
+
// 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"
|
|
1669
|
+
// rather than just timing out, as expected.
|
|
1670
|
+
logger$h.info(`${msiName$1}: The Azure IMDS endpoint is unavailable`);
|
|
1671
|
+
return false;
|
|
1672
|
+
}
|
|
1673
|
+
if (response.status === 403) {
|
|
1674
|
+
if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("unreachable")) {
|
|
1675
|
+
logger$h.info(`${msiName$1}: The Azure IMDS endpoint is unavailable`);
|
|
1676
|
+
logger$h.info(`${msiName$1}: ${response.bodyAsText}`);
|
|
1677
|
+
return false;
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
// If we received any response, the endpoint is available
|
|
1681
|
+
logger$h.info(`${msiName$1}: The Azure IMDS endpoint is available`);
|
|
1682
|
+
return true;
|
|
1683
|
+
});
|
|
1684
|
+
},
|
|
1685
|
+
async getToken(configuration, getTokenOptions = {}) {
|
|
1686
|
+
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
1687
|
+
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
1688
|
+
logger$h.info(`${msiName$1}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
logger$h.info(`${msiName$1}: Using the default Azure IMDS endpoint ${imdsHost}.`);
|
|
1692
|
+
}
|
|
1693
|
+
let nextDelayInMs = configuration.retryConfig.startDelayInMs;
|
|
1694
|
+
for (let retries = 0; retries < configuration.retryConfig.maxRetries; retries++) {
|
|
1695
|
+
try {
|
|
1696
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
|
|
1697
|
+
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1698
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1699
|
+
}
|
|
1700
|
+
catch (error) {
|
|
1701
|
+
if (error.statusCode === 404) {
|
|
1702
|
+
await coreUtil.delay(nextDelayInMs);
|
|
1703
|
+
nextDelayInMs *= configuration.retryConfig.intervalIncrement;
|
|
1704
|
+
continue;
|
|
1705
|
+
}
|
|
1706
|
+
throw error;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
throw new AuthenticationError(404, `${msiName$1}: Failed to retrieve IMDS token after ${configuration.retryConfig.maxRetries} retries.`);
|
|
1710
|
+
},
|
|
1711
|
+
};
|
|
1560
1712
|
|
|
1561
1713
|
// Copyright (c) Microsoft Corporation.
|
|
1562
1714
|
// Licensed under the MIT license.
|
|
@@ -2047,7 +2199,7 @@ class MsalClientAssertion extends MsalNode {
|
|
|
2047
2199
|
|
|
2048
2200
|
// Copyright (c) Microsoft Corporation.
|
|
2049
2201
|
// Licensed under the MIT license.
|
|
2050
|
-
const logger$
|
|
2202
|
+
const logger$g = credentialLogger("ClientAssertionCredential");
|
|
2051
2203
|
/**
|
|
2052
2204
|
* Authenticates a service principal with a JWT assertion.
|
|
2053
2205
|
*/
|
|
@@ -2070,7 +2222,7 @@ class ClientAssertionCredential {
|
|
|
2070
2222
|
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
2071
2223
|
this.clientId = clientId;
|
|
2072
2224
|
this.options = options;
|
|
2073
|
-
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$
|
|
2225
|
+
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$g, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
|
|
2074
2226
|
}
|
|
2075
2227
|
/**
|
|
2076
2228
|
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
@@ -2082,7 +2234,7 @@ class ClientAssertionCredential {
|
|
|
2082
2234
|
*/
|
|
2083
2235
|
async getToken(scopes, options = {}) {
|
|
2084
2236
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
2085
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$
|
|
2237
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$g);
|
|
2086
2238
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
2087
2239
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
2088
2240
|
});
|
|
@@ -2104,7 +2256,7 @@ const SupportedWorkloadEnvironmentVariables = [
|
|
|
2104
2256
|
"AZURE_CLIENT_ID",
|
|
2105
2257
|
"AZURE_FEDERATED_TOKEN_FILE",
|
|
2106
2258
|
];
|
|
2107
|
-
const logger$
|
|
2259
|
+
const logger$f = credentialLogger(credentialName$3);
|
|
2108
2260
|
/**
|
|
2109
2261
|
* Workload Identity authentication is a feature in Azure that allows applications running on virtual machines (VMs)
|
|
2110
2262
|
* to access other Azure resources without the need for a service principal or managed identity. With Workload Identity
|
|
@@ -2130,17 +2282,17 @@ class WorkloadIdentityCredential {
|
|
|
2130
2282
|
this.cacheDate = undefined;
|
|
2131
2283
|
// Logging environment variables for error details
|
|
2132
2284
|
const assignedEnv = processEnvVars(SupportedWorkloadEnvironmentVariables).assigned.join(", ");
|
|
2133
|
-
logger$
|
|
2285
|
+
logger$f.info(`Found the following environment variables: ${assignedEnv}`);
|
|
2134
2286
|
const workloadIdentityCredentialOptions = options !== null && options !== void 0 ? options : {};
|
|
2135
2287
|
const tenantId = workloadIdentityCredentialOptions.tenantId || process.env.AZURE_TENANT_ID;
|
|
2136
2288
|
const clientId = workloadIdentityCredentialOptions.clientId || process.env.AZURE_CLIENT_ID;
|
|
2137
2289
|
this.federatedTokenFilePath =
|
|
2138
2290
|
workloadIdentityCredentialOptions.tokenFilePath || process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
2139
2291
|
if (tenantId) {
|
|
2140
|
-
checkTenantId(logger$
|
|
2292
|
+
checkTenantId(logger$f, tenantId);
|
|
2141
2293
|
}
|
|
2142
2294
|
if (clientId && tenantId && this.federatedTokenFilePath) {
|
|
2143
|
-
logger$
|
|
2295
|
+
logger$f.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
|
|
2144
2296
|
this.client = new ClientAssertionCredential(tenantId, clientId, this.readFileContents.bind(this), options);
|
|
2145
2297
|
}
|
|
2146
2298
|
}
|
|
@@ -2159,10 +2311,10 @@ class WorkloadIdentityCredential {
|
|
|
2159
2311
|
"AZURE_TENANT_ID",
|
|
2160
2312
|
"AZURE_CLIENT_ID",
|
|
2161
2313
|
"AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot `;
|
|
2162
|
-
logger$
|
|
2314
|
+
logger$f.info(errorMessage);
|
|
2163
2315
|
throw new CredentialUnavailableError(errorMessage);
|
|
2164
2316
|
}
|
|
2165
|
-
logger$
|
|
2317
|
+
logger$f.info("Invoking getToken() of Client Assertion Credential");
|
|
2166
2318
|
return this.client.getToken(scopes, options);
|
|
2167
2319
|
}
|
|
2168
2320
|
async readFileContents() {
|
|
@@ -2190,8 +2342,8 @@ class WorkloadIdentityCredential {
|
|
|
2190
2342
|
|
|
2191
2343
|
// Copyright (c) Microsoft Corporation.
|
|
2192
2344
|
// Licensed under the MIT license.
|
|
2193
|
-
const msiName
|
|
2194
|
-
const logger$
|
|
2345
|
+
const msiName = "ManagedIdentityCredential - Token Exchange";
|
|
2346
|
+
const logger$e = credentialLogger(msiName);
|
|
2195
2347
|
/**
|
|
2196
2348
|
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
|
|
2197
2349
|
*/
|
|
@@ -2204,7 +2356,7 @@ function tokenExchangeMsi() {
|
|
|
2204
2356
|
env.AZURE_TENANT_ID &&
|
|
2205
2357
|
process.env.AZURE_FEDERATED_TOKEN_FILE);
|
|
2206
2358
|
if (!result) {
|
|
2207
|
-
logger$
|
|
2359
|
+
logger$e.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`);
|
|
2208
2360
|
}
|
|
2209
2361
|
return result;
|
|
2210
2362
|
},
|
|
@@ -2218,164 +2370,6 @@ function tokenExchangeMsi() {
|
|
|
2218
2370
|
};
|
|
2219
2371
|
}
|
|
2220
2372
|
|
|
2221
|
-
// Copyright (c) Microsoft Corporation.
|
|
2222
|
-
// Licensed under the MIT license.
|
|
2223
|
-
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
|
|
2224
|
-
//
|
|
2225
|
-
// FROM node:12
|
|
2226
|
-
// RUN wget https://host.any/path/bash.sh
|
|
2227
|
-
// CMD ["bash", "bash.sh"]
|
|
2228
|
-
//
|
|
2229
|
-
// Where the bash script contains:
|
|
2230
|
-
//
|
|
2231
|
-
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
2232
|
-
//
|
|
2233
|
-
const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
|
|
2234
|
-
const logger$f = credentialLogger(msiName$1);
|
|
2235
|
-
/**
|
|
2236
|
-
* Generates the options used on the request for an access token.
|
|
2237
|
-
*/
|
|
2238
|
-
function prepareRequestOptions$1(scopes, clientId, resourceId) {
|
|
2239
|
-
const resource = mapScopesToResource(scopes);
|
|
2240
|
-
if (!resource) {
|
|
2241
|
-
throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
|
|
2242
|
-
}
|
|
2243
|
-
const queryParameters = {
|
|
2244
|
-
resource,
|
|
2245
|
-
"api-version": azureFabricVersion,
|
|
2246
|
-
};
|
|
2247
|
-
if (clientId) {
|
|
2248
|
-
queryParameters.client_id = clientId;
|
|
2249
|
-
}
|
|
2250
|
-
if (resourceId) {
|
|
2251
|
-
queryParameters.msi_res_id = resourceId;
|
|
2252
|
-
}
|
|
2253
|
-
const query = new URLSearchParams(queryParameters);
|
|
2254
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2255
|
-
if (!process.env.IDENTITY_ENDPOINT) {
|
|
2256
|
-
throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
|
|
2257
|
-
}
|
|
2258
|
-
if (!process.env.IDENTITY_HEADER) {
|
|
2259
|
-
throw new Error("Missing environment variable: IDENTITY_HEADER");
|
|
2260
|
-
}
|
|
2261
|
-
return {
|
|
2262
|
-
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
|
2263
|
-
method: "GET",
|
|
2264
|
-
headers: coreRestPipeline.createHttpHeaders({
|
|
2265
|
-
Accept: "application/json",
|
|
2266
|
-
secret: process.env.IDENTITY_HEADER,
|
|
2267
|
-
}),
|
|
2268
|
-
};
|
|
2269
|
-
}
|
|
2270
|
-
/**
|
|
2271
|
-
* 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.
|
|
2272
|
-
*/
|
|
2273
|
-
const fabricMsi = {
|
|
2274
|
-
name: "fabricMsi",
|
|
2275
|
-
async isAvailable({ scopes }) {
|
|
2276
|
-
const resource = mapScopesToResource(scopes);
|
|
2277
|
-
if (!resource) {
|
|
2278
|
-
logger$f.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
|
|
2279
|
-
return false;
|
|
2280
|
-
}
|
|
2281
|
-
const env = process.env;
|
|
2282
|
-
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
|
|
2283
|
-
if (!result) {
|
|
2284
|
-
logger$f.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
|
|
2285
|
-
}
|
|
2286
|
-
return result;
|
|
2287
|
-
},
|
|
2288
|
-
async getToken(configuration, getTokenOptions = {}) {
|
|
2289
|
-
const { scopes, identityClient, clientId, resourceId } = configuration;
|
|
2290
|
-
if (resourceId) {
|
|
2291
|
-
logger$f.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2292
|
-
}
|
|
2293
|
-
logger$f.info([
|
|
2294
|
-
`${msiName$1}:`,
|
|
2295
|
-
"Using the endpoint and the secret coming from the environment variables:",
|
|
2296
|
-
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
|
|
2297
|
-
"IDENTITY_HEADER=[REDACTED] and",
|
|
2298
|
-
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
|
|
2299
|
-
].join(" "));
|
|
2300
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
|
|
2301
|
-
request.agent = new https.Agent({
|
|
2302
|
-
// This is necessary because Service Fabric provides a self-signed certificate.
|
|
2303
|
-
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
|
2304
|
-
rejectUnauthorized: false,
|
|
2305
|
-
});
|
|
2306
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
2307
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2308
|
-
},
|
|
2309
|
-
};
|
|
2310
|
-
|
|
2311
|
-
// Copyright (c) Microsoft Corporation.
|
|
2312
|
-
// Licensed under the MIT license.
|
|
2313
|
-
const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
|
|
2314
|
-
const logger$e = credentialLogger(msiName);
|
|
2315
|
-
/**
|
|
2316
|
-
* Generates the options used on the request for an access token.
|
|
2317
|
-
*/
|
|
2318
|
-
function prepareRequestOptions(scopes, clientId, resourceId) {
|
|
2319
|
-
const resource = mapScopesToResource(scopes);
|
|
2320
|
-
if (!resource) {
|
|
2321
|
-
throw new Error(`${msiName}: Multiple scopes are not supported.`);
|
|
2322
|
-
}
|
|
2323
|
-
const queryParameters = {
|
|
2324
|
-
resource,
|
|
2325
|
-
"api-version": "2019-08-01",
|
|
2326
|
-
};
|
|
2327
|
-
if (clientId) {
|
|
2328
|
-
queryParameters.client_id = clientId;
|
|
2329
|
-
}
|
|
2330
|
-
if (resourceId) {
|
|
2331
|
-
queryParameters.mi_res_id = resourceId;
|
|
2332
|
-
}
|
|
2333
|
-
const query = new URLSearchParams(queryParameters);
|
|
2334
|
-
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
|
|
2335
|
-
if (!process.env.IDENTITY_ENDPOINT) {
|
|
2336
|
-
throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
|
|
2337
|
-
}
|
|
2338
|
-
if (!process.env.IDENTITY_HEADER) {
|
|
2339
|
-
throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
|
|
2340
|
-
}
|
|
2341
|
-
return {
|
|
2342
|
-
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
|
|
2343
|
-
method: "GET",
|
|
2344
|
-
headers: coreRestPipeline.createHttpHeaders({
|
|
2345
|
-
Accept: "application/json",
|
|
2346
|
-
"X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
|
|
2347
|
-
}),
|
|
2348
|
-
};
|
|
2349
|
-
}
|
|
2350
|
-
/**
|
|
2351
|
-
* 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.
|
|
2352
|
-
*/
|
|
2353
|
-
const appServiceMsi2019 = {
|
|
2354
|
-
name: "appServiceMsi2019",
|
|
2355
|
-
async isAvailable({ scopes }) {
|
|
2356
|
-
const resource = mapScopesToResource(scopes);
|
|
2357
|
-
if (!resource) {
|
|
2358
|
-
logger$e.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
|
|
2359
|
-
return false;
|
|
2360
|
-
}
|
|
2361
|
-
const env = process.env;
|
|
2362
|
-
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
|
|
2363
|
-
if (!result) {
|
|
2364
|
-
logger$e.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
|
|
2365
|
-
}
|
|
2366
|
-
return result;
|
|
2367
|
-
},
|
|
2368
|
-
async getToken(configuration, getTokenOptions = {}) {
|
|
2369
|
-
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2370
|
-
logger$e.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
|
2371
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
|
|
2372
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2373
|
-
allowInsecureConnection: true }));
|
|
2374
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
2375
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2376
|
-
},
|
|
2377
|
-
};
|
|
2378
|
-
|
|
2379
2373
|
// Copyright (c) Microsoft Corporation.
|
|
2380
2374
|
// Licensed under the MIT license.
|
|
2381
2375
|
const logger$d = credentialLogger("ManagedIdentityCredential");
|
|
@@ -2393,9 +2387,14 @@ class ManagedIdentityCredential {
|
|
|
2393
2387
|
* @hidden
|
|
2394
2388
|
*/
|
|
2395
2389
|
constructor(clientIdOrOptions, options) {
|
|
2396
|
-
var _a;
|
|
2390
|
+
var _a, _b;
|
|
2397
2391
|
this.isEndpointUnavailable = null;
|
|
2398
2392
|
this.isAppTokenProviderInitialized = false;
|
|
2393
|
+
this.msiRetryConfig = {
|
|
2394
|
+
maxRetries: 3,
|
|
2395
|
+
startDelayInMs: 800,
|
|
2396
|
+
intervalIncrement: 2,
|
|
2397
|
+
};
|
|
2399
2398
|
let _options;
|
|
2400
2399
|
if (typeof clientIdOrOptions === "string") {
|
|
2401
2400
|
this.clientId = clientIdOrOptions;
|
|
@@ -2410,6 +2409,9 @@ class ManagedIdentityCredential {
|
|
|
2410
2409
|
if (this.clientId && this.resourceId) {
|
|
2411
2410
|
throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
|
|
2412
2411
|
}
|
|
2412
|
+
if (((_a = _options === null || _options === void 0 ? void 0 : _options.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== undefined) {
|
|
2413
|
+
this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;
|
|
2414
|
+
}
|
|
2413
2415
|
this.identityClient = new IdentityClient(_options);
|
|
2414
2416
|
this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
|
|
2415
2417
|
maxRetries: 0,
|
|
@@ -2420,7 +2422,7 @@ class ManagedIdentityCredential {
|
|
|
2420
2422
|
this.confidentialApp = new msalCommon.ConfidentialClientApplication({
|
|
2421
2423
|
auth: {
|
|
2422
2424
|
authority: "https://login.microsoftonline.com/managed_identity",
|
|
2423
|
-
clientId: (
|
|
2425
|
+
clientId: (_b = this.clientId) !== null && _b !== void 0 ? _b : DeveloperSignOnClientId,
|
|
2424
2426
|
clientSecret: "dummy-secret",
|
|
2425
2427
|
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"]}]}',
|
|
2426
2428
|
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"}',
|
|
@@ -2470,6 +2472,7 @@ class ManagedIdentityCredential {
|
|
|
2470
2472
|
scopes,
|
|
2471
2473
|
clientId: this.clientId,
|
|
2472
2474
|
resourceId: this.resourceId,
|
|
2475
|
+
retryConfig: this.msiRetryConfig,
|
|
2473
2476
|
}, updatedOptions);
|
|
2474
2477
|
}
|
|
2475
2478
|
catch (err) {
|
|
@@ -2576,10 +2579,10 @@ class ManagedIdentityCredential {
|
|
|
2576
2579
|
if (err.statusCode === 400) {
|
|
2577
2580
|
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
|
|
2578
2581
|
}
|
|
2579
|
-
// 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"
|
|
2582
|
+
// 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"
|
|
2580
2583
|
// rather than just timing out, as expected.
|
|
2581
2584
|
if (err.statusCode === 403 || err.code === 403) {
|
|
2582
|
-
if (err.message.includes("
|
|
2585
|
+
if (err.message.includes("unreachable")) {
|
|
2583
2586
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
|
|
2584
2587
|
logger$d.getToken.info(formatError(scopes, error));
|
|
2585
2588
|
throw error;
|
|
@@ -3762,13 +3765,17 @@ const logger$4 = credentialLogger("DefaultAzureCredential");
|
|
|
3762
3765
|
*
|
|
3763
3766
|
* @internal
|
|
3764
3767
|
*/
|
|
3765
|
-
function createDefaultManagedIdentityCredential(options) {
|
|
3766
|
-
var _a, _b, _c;
|
|
3767
|
-
|
|
3768
|
-
|
|
3768
|
+
function createDefaultManagedIdentityCredential(options = {}) {
|
|
3769
|
+
var _a, _b, _c, _d;
|
|
3770
|
+
(_a = options.retryOptions) !== null && _a !== void 0 ? _a : (options.retryOptions = {
|
|
3771
|
+
maxRetries: 5,
|
|
3772
|
+
retryDelayInMs: 800,
|
|
3773
|
+
});
|
|
3774
|
+
const managedIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
|
|
3775
|
+
const workloadIdentityClientId = (_c = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _c !== void 0 ? _c : managedIdentityClientId;
|
|
3769
3776
|
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
|
|
3770
3777
|
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3771
|
-
const tenantId = (
|
|
3778
|
+
const tenantId = (_d = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _d !== void 0 ? _d : process.env.AZURE_TENANT_ID;
|
|
3772
3779
|
if (managedResourceId) {
|
|
3773
3780
|
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
|
|
3774
3781
|
return new ManagedIdentityCredential(managedIdentityResourceIdOptions);
|