@azure/identity 4.4.0 → 4.4.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.
- 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 +1 -1
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.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
|