@azure/identity 1.2.0-beta.2 → 1.2.0
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/CHANGELOG.md +24 -2
- package/README.md +75 -55
- package/dist/index.js +533 -396
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/msalClient.js +138 -0
- package/dist-esm/src/client/msalClient.js.map +1 -0
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +3 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.browser.js +2 -2
- package/dist-esm/src/credentials/azureCliCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +5 -5
- package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/chainedTokenCredential.js +2 -2
- package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js +2 -2
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.js +5 -3
- package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.js +2 -2
- package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +53 -47
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.browser.js +2 -2
- package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.js +6 -2
- package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +7 -5
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.js +30 -69
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +44 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +74 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +41 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js +8 -0
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +59 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +109 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -0
- package/dist-esm/src/credentials/{managedIdentityCredential.browser.js → managedIdentityCredential/index.browser.js} +4 -4
- package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +165 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/models.js +3 -0
- package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js +28 -0
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -0
- package/dist-esm/src/credentials/usernamePasswordCredential.js +3 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.js +19 -8
- package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/util/checkTenantId.js +11 -0
- package/dist-esm/src/util/checkTenantId.js.map +1 -0
- package/dist-esm/src/util/logging.js +7 -3
- package/dist-esm/src/util/logging.js.map +1 -1
- package/package.json +7 -5
- package/types/identity.d.ts +9 -33
- package/dist-esm/src/credentials/managedIdentityCredential.browser.js.map +0 -1
- package/dist-esm/src/credentials/managedIdentityCredential.js +0 -376
- package/dist-esm/src/credentials/managedIdentityCredential.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
|
|
|
7
7
|
var tslib = require('tslib');
|
|
8
8
|
var coreTracing = require('@azure/core-tracing');
|
|
9
9
|
var api = require('@opentelemetry/api');
|
|
10
|
-
var logger$
|
|
10
|
+
var logger$h = require('@azure/logger');
|
|
11
11
|
var qs = _interopDefault(require('qs'));
|
|
12
12
|
var coreHttp = require('@azure/core-http');
|
|
13
13
|
var jws = _interopDefault(require('jws'));
|
|
@@ -19,6 +19,8 @@ var crypto__default = _interopDefault(crypto);
|
|
|
19
19
|
var child_process = require('child_process');
|
|
20
20
|
var os = _interopDefault(require('os'));
|
|
21
21
|
var path$2 = _interopDefault(require('path'));
|
|
22
|
+
var msalNode = require('@azure/msal-node');
|
|
23
|
+
require('axios');
|
|
22
24
|
var events = _interopDefault(require('events'));
|
|
23
25
|
var util = _interopDefault(require('util'));
|
|
24
26
|
var tty = _interopDefault(require('tty'));
|
|
@@ -30,7 +32,6 @@ var zlib = _interopDefault(require('zlib'));
|
|
|
30
32
|
var querystring = _interopDefault(require('querystring'));
|
|
31
33
|
var url = _interopDefault(require('url'));
|
|
32
34
|
var http = _interopDefault(require('http'));
|
|
33
|
-
var msalNode = require('@azure/msal-node');
|
|
34
35
|
var open = _interopDefault(require('open'));
|
|
35
36
|
|
|
36
37
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -154,7 +155,7 @@ function createSpan(operationName, options = {}) {
|
|
|
154
155
|
/**
|
|
155
156
|
* The AzureLogger used for all clients within the identity package
|
|
156
157
|
*/
|
|
157
|
-
const logger = logger$
|
|
158
|
+
const logger = logger$h.createClientLogger("identity");
|
|
158
159
|
/**
|
|
159
160
|
* 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.
|
|
160
161
|
* @param supportedEnvVars List of environment variable names
|
|
@@ -174,13 +175,17 @@ function processEnvVars(supportedEnvVars) {
|
|
|
174
175
|
* Formatting the success event on the credentials
|
|
175
176
|
*/
|
|
176
177
|
function formatSuccess(scope) {
|
|
177
|
-
return `SUCCESS: ${Array.isArray(scope) ? scope.join(", ") : scope}
|
|
178
|
+
return `SUCCESS. Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`;
|
|
178
179
|
}
|
|
179
180
|
/**
|
|
180
181
|
* Formatting the success event on the credentials
|
|
181
182
|
*/
|
|
182
|
-
function formatError(error) {
|
|
183
|
-
|
|
183
|
+
function formatError(scope, error) {
|
|
184
|
+
let message = "ERROR.";
|
|
185
|
+
if (scope === null || scope === void 0 ? void 0 : scope.length) {
|
|
186
|
+
message += ` Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`;
|
|
187
|
+
}
|
|
188
|
+
return `${message} Error message: ${typeof error === "string" ? error : error.message}.`;
|
|
184
189
|
}
|
|
185
190
|
/**
|
|
186
191
|
* Generates a CredentialLoggerInstance.
|
|
@@ -270,7 +275,7 @@ class ChainedTokenCredential {
|
|
|
270
275
|
errors.push(err);
|
|
271
276
|
}
|
|
272
277
|
else {
|
|
273
|
-
logger$1.getToken.info(formatError(err));
|
|
278
|
+
logger$1.getToken.info(formatError(scopes, err));
|
|
274
279
|
throw err;
|
|
275
280
|
}
|
|
276
281
|
}
|
|
@@ -281,7 +286,7 @@ class ChainedTokenCredential {
|
|
|
281
286
|
code: api.CanonicalCode.UNAUTHENTICATED,
|
|
282
287
|
message: err.message
|
|
283
288
|
});
|
|
284
|
-
logger$1.getToken.info(formatError(err));
|
|
289
|
+
logger$1.getToken.info(formatError(scopes, err));
|
|
285
290
|
throw err;
|
|
286
291
|
}
|
|
287
292
|
span.end();
|
|
@@ -527,7 +532,7 @@ class ClientSecretCredential {
|
|
|
527
532
|
code,
|
|
528
533
|
message: err.message
|
|
529
534
|
});
|
|
530
|
-
logger$2.getToken.info(err);
|
|
535
|
+
logger$2.getToken.info(formatError(scopes, err));
|
|
531
536
|
throw err;
|
|
532
537
|
}
|
|
533
538
|
finally {
|
|
@@ -537,6 +542,15 @@ class ClientSecretCredential {
|
|
|
537
542
|
}
|
|
538
543
|
}
|
|
539
544
|
|
|
545
|
+
// Copyright (c) Microsoft Corporation.
|
|
546
|
+
function checkTenantId(logger, tenantId) {
|
|
547
|
+
if (!tenantId.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
548
|
+
const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://docs.microsoft.com/partner-center/find-ids-and-domain-names.");
|
|
549
|
+
logger.info(formatError("", error));
|
|
550
|
+
throw error;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
540
554
|
// Copyright (c) Microsoft Corporation.
|
|
541
555
|
const SelfSignedJwtLifetimeMins = 10;
|
|
542
556
|
function timestampInSeconds(date) {
|
|
@@ -566,6 +580,7 @@ class ClientCertificateCredential {
|
|
|
566
580
|
* @param options Options for configuring the client which makes the authentication request.
|
|
567
581
|
*/
|
|
568
582
|
constructor(tenantId, clientId, certificatePath, options) {
|
|
583
|
+
checkTenantId(logger$3, tenantId);
|
|
569
584
|
this.identityClient = new IdentityClient(options);
|
|
570
585
|
this.tenantId = tenantId;
|
|
571
586
|
this.clientId = clientId;
|
|
@@ -582,7 +597,7 @@ class ClientCertificateCredential {
|
|
|
582
597
|
} while (match);
|
|
583
598
|
if (publicKeys.length === 0) {
|
|
584
599
|
const error = new Error("The file at the specified path does not contain a PEM-encoded certificate.");
|
|
585
|
-
logger$3.info(formatError(error));
|
|
600
|
+
logger$3.info(formatError("", error));
|
|
586
601
|
throw error;
|
|
587
602
|
}
|
|
588
603
|
this.certificateThumbprint = crypto.createHash("sha1")
|
|
@@ -590,7 +605,7 @@ class ClientCertificateCredential {
|
|
|
590
605
|
.digest("hex")
|
|
591
606
|
.toUpperCase();
|
|
592
607
|
this.certificateX5t = Buffer.from(this.certificateThumbprint, "hex").toString("base64");
|
|
593
|
-
if (options && options.
|
|
608
|
+
if (options && options.sendCertificateChain) {
|
|
594
609
|
this.certificateX5c = publicKeys;
|
|
595
610
|
}
|
|
596
611
|
}
|
|
@@ -672,7 +687,7 @@ class ClientCertificateCredential {
|
|
|
672
687
|
code,
|
|
673
688
|
message: err.message
|
|
674
689
|
});
|
|
675
|
-
logger$3.getToken.info(formatError(err));
|
|
690
|
+
logger$3.getToken.info(formatError("", err));
|
|
676
691
|
throw err;
|
|
677
692
|
}
|
|
678
693
|
finally {
|
|
@@ -703,6 +718,7 @@ class UsernamePasswordCredential {
|
|
|
703
718
|
* @param options Options for configuring the client which makes the authentication request.
|
|
704
719
|
*/
|
|
705
720
|
constructor(tenantIdOrName, clientId, username, password, options) {
|
|
721
|
+
checkTenantId(logger$4, tenantIdOrName);
|
|
706
722
|
this.identityClient = new IdentityClient(options);
|
|
707
723
|
this.tenantId = tenantIdOrName;
|
|
708
724
|
this.clientId = clientId;
|
|
@@ -756,7 +772,7 @@ class UsernamePasswordCredential {
|
|
|
756
772
|
code,
|
|
757
773
|
message: err.message
|
|
758
774
|
});
|
|
759
|
-
logger$4.getToken.info(formatError(err));
|
|
775
|
+
logger$4.getToken.info(formatError(scopes, err));
|
|
760
776
|
throw err;
|
|
761
777
|
}
|
|
762
778
|
finally {
|
|
@@ -810,6 +826,9 @@ class EnvironmentCredential {
|
|
|
810
826
|
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
|
|
811
827
|
logger$5.info(`Found the following environment variables: ${assigned}`);
|
|
812
828
|
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
829
|
+
if (tenantId) {
|
|
830
|
+
checkTenantId(logger$5, tenantId);
|
|
831
|
+
}
|
|
813
832
|
if (tenantId && clientId && clientSecret) {
|
|
814
833
|
logger$5.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
|
|
815
834
|
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
|
|
@@ -862,7 +881,7 @@ class EnvironmentCredential {
|
|
|
862
881
|
.split("More details:")
|
|
863
882
|
.join("")
|
|
864
883
|
});
|
|
865
|
-
logger$5.getToken.info(formatError(authenticationError));
|
|
884
|
+
logger$5.getToken.info(formatError(scopes, authenticationError));
|
|
866
885
|
throw authenticationError;
|
|
867
886
|
}
|
|
868
887
|
finally {
|
|
@@ -874,137 +893,119 @@ class EnvironmentCredential {
|
|
|
874
893
|
span.setStatus({ code: api.CanonicalCode.UNAUTHENTICATED });
|
|
875
894
|
span.end();
|
|
876
895
|
const error = new CredentialUnavailable("EnvironmentCredential is unavailable. Environment variables are not fully configured.");
|
|
877
|
-
logger$5.getToken.info(formatError(error));
|
|
896
|
+
logger$5.getToken.info(formatError(scopes, error));
|
|
878
897
|
throw error;
|
|
879
898
|
});
|
|
880
899
|
}
|
|
881
900
|
}
|
|
882
901
|
|
|
883
902
|
// Copyright (c) Microsoft Corporation.
|
|
903
|
+
// Licensed under the MIT license.
|
|
884
904
|
const DefaultScopeSuffix = "/.default";
|
|
885
|
-
const
|
|
886
|
-
const
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
*
|
|
896
|
-
* https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
|
|
897
|
-
*/
|
|
898
|
-
class ManagedIdentityCredential {
|
|
899
|
-
/**
|
|
900
|
-
* @internal
|
|
901
|
-
* @ignore
|
|
902
|
-
*/
|
|
903
|
-
constructor(clientIdOrOptions, options) {
|
|
904
|
-
this.isEndpointUnavailable = null;
|
|
905
|
-
if (typeof clientIdOrOptions === "string") {
|
|
906
|
-
// clientId, options constructor
|
|
907
|
-
this.clientId = clientIdOrOptions;
|
|
908
|
-
this.identityClient = new IdentityClient(options);
|
|
909
|
-
}
|
|
910
|
-
else {
|
|
911
|
-
// options only constructor
|
|
912
|
-
this.identityClient = new IdentityClient(clientIdOrOptions);
|
|
905
|
+
const imdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";
|
|
906
|
+
const imdsApiVersion = "2018-02-01";
|
|
907
|
+
const azureArcAPIVersion = "2019-11-01";
|
|
908
|
+
|
|
909
|
+
// Copyright (c) Microsoft Corporation.
|
|
910
|
+
function mapScopesToResource(scopes) {
|
|
911
|
+
let scope = "";
|
|
912
|
+
if (Array.isArray(scopes)) {
|
|
913
|
+
if (scopes.length !== 1) {
|
|
914
|
+
throw new Error("To convert to a resource string the specified array must be exactly length 1");
|
|
913
915
|
}
|
|
916
|
+
scope = scopes[0];
|
|
914
917
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (Array.isArray(scopes)) {
|
|
918
|
-
if (scopes.length !== 1) {
|
|
919
|
-
throw new Error("To convert to a resource string the specified array must be exactly length 1");
|
|
920
|
-
}
|
|
921
|
-
scope = scopes[0];
|
|
922
|
-
}
|
|
923
|
-
else if (typeof scopes === "string") {
|
|
924
|
-
scope = scopes;
|
|
925
|
-
}
|
|
926
|
-
if (!scope.endsWith(DefaultScopeSuffix)) {
|
|
927
|
-
return scope;
|
|
928
|
-
}
|
|
929
|
-
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
|
|
918
|
+
else if (typeof scopes === "string") {
|
|
919
|
+
scope = scopes;
|
|
930
920
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
resource,
|
|
934
|
-
"api-version": ImdsApiVersion
|
|
935
|
-
};
|
|
936
|
-
if (clientId) {
|
|
937
|
-
queryParameters.client_id = clientId;
|
|
938
|
-
}
|
|
939
|
-
return {
|
|
940
|
-
url: ImdsEndpoint,
|
|
941
|
-
method: "GET",
|
|
942
|
-
queryParameters,
|
|
943
|
-
headers: {
|
|
944
|
-
Accept: "application/json",
|
|
945
|
-
Metadata: true
|
|
946
|
-
}
|
|
947
|
-
};
|
|
921
|
+
if (!scope.endsWith(DefaultScopeSuffix)) {
|
|
922
|
+
return scope;
|
|
948
923
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
if (clientId) {
|
|
970
|
-
queryParameters.clientid = clientId;
|
|
971
|
-
}
|
|
972
|
-
return {
|
|
973
|
-
url: process.env.MSI_ENDPOINT,
|
|
974
|
-
method: "GET",
|
|
975
|
-
queryParameters,
|
|
976
|
-
headers: {
|
|
977
|
-
Accept: "application/json",
|
|
978
|
-
secret: process.env.MSI_SECRET
|
|
979
|
-
}
|
|
980
|
-
};
|
|
981
|
-
}
|
|
982
|
-
else {
|
|
983
|
-
throw new Error(`Unsupported version ${version}. The supported versions are "2019-08-01" and "2017-09-01"`);
|
|
984
|
-
}
|
|
924
|
+
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
|
|
925
|
+
}
|
|
926
|
+
function msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions = {}) {
|
|
927
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
928
|
+
const webResource = identityClient.createWebResource(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions }, requestOptions));
|
|
929
|
+
const tokenResponse = yield identityClient.sendTokenRequest(webResource, expiresInParser);
|
|
930
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Copyright (c) Microsoft Corporation.
|
|
935
|
+
const logger$6 = credentialLogger("ManagedIdentityCredential - CloudShellMSI");
|
|
936
|
+
// Cloud Shell MSI doesn't have a special expiresIn parser.
|
|
937
|
+
const expiresInParser = undefined;
|
|
938
|
+
function prepareRequestOptions(resource, clientId) {
|
|
939
|
+
const body = {
|
|
940
|
+
resource
|
|
941
|
+
};
|
|
942
|
+
if (clientId) {
|
|
943
|
+
body.client_id = clientId;
|
|
985
944
|
}
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
945
|
+
return {
|
|
946
|
+
url: process.env.MSI_ENDPOINT,
|
|
947
|
+
method: "POST",
|
|
948
|
+
body: qs.stringify(body),
|
|
949
|
+
headers: {
|
|
950
|
+
Accept: "application/json",
|
|
951
|
+
Metadata: true,
|
|
952
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
992
953
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
const cloudShellMsi = {
|
|
957
|
+
isAvailable() {
|
|
958
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
959
|
+
return Boolean(process.env.MSI_ENDPOINT);
|
|
960
|
+
});
|
|
961
|
+
},
|
|
962
|
+
getToken(identityClient, resource, clientId, getTokenOptions = {}) {
|
|
963
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
964
|
+
logger$6.info(`Using the endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the Cloud Shell to proceed with the authentication.`);
|
|
965
|
+
return msiGenericGetToken(identityClient, prepareRequestOptions(resource, clientId), expiresInParser, getTokenOptions);
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
|
|
970
|
+
// Copyright (c) Microsoft Corporation.
|
|
971
|
+
const logger$7 = credentialLogger("ManagedIdentityCredential - IMDS");
|
|
972
|
+
function expiresInParser$1(requestBody) {
|
|
973
|
+
if (requestBody.expires_on) {
|
|
974
|
+
// Use the expires_on timestamp if it's available
|
|
975
|
+
const expires = +requestBody.expires_on * 1000;
|
|
976
|
+
logger$7.info(`IMDS using expires_on: ${expires} (original value: ${requestBody.expires_on})`);
|
|
977
|
+
return expires;
|
|
1003
978
|
}
|
|
1004
|
-
|
|
979
|
+
else {
|
|
980
|
+
// If these aren't possible, use expires_in and calculate a timestamp
|
|
981
|
+
const expires = Date.now() + requestBody.expires_in * 1000;
|
|
982
|
+
logger$7.info(`IMDS using expires_in: ${expires} (original value: ${requestBody.expires_in})`);
|
|
983
|
+
return expires;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
function prepareRequestOptions$1(resource, clientId) {
|
|
987
|
+
const queryParameters = {
|
|
988
|
+
resource,
|
|
989
|
+
"api-version": imdsApiVersion
|
|
990
|
+
};
|
|
991
|
+
if (clientId) {
|
|
992
|
+
queryParameters.client_id = clientId;
|
|
993
|
+
}
|
|
994
|
+
return {
|
|
995
|
+
url: imdsEndpoint,
|
|
996
|
+
method: "GET",
|
|
997
|
+
queryParameters,
|
|
998
|
+
headers: {
|
|
999
|
+
Accept: "application/json",
|
|
1000
|
+
Metadata: true
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
const imdsMsi = {
|
|
1005
|
+
isAvailable(identityClient, resource, clientId, getTokenOptions) {
|
|
1005
1006
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1006
1007
|
const { span, options } = createSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions);
|
|
1007
|
-
const request =
|
|
1008
|
+
const request = prepareRequestOptions$1(resource, clientId);
|
|
1008
1009
|
// This will always be populated, but let's make TypeScript happy
|
|
1009
1010
|
if (request.headers) {
|
|
1010
1011
|
// Remove the Metadata header to invoke a request error from
|
|
@@ -1016,11 +1017,11 @@ class ManagedIdentityCredential {
|
|
|
1016
1017
|
// Create a request with a timeout since we expect that
|
|
1017
1018
|
// not having a "Metadata" header should cause an error to be
|
|
1018
1019
|
// returned quickly from the endpoint, proving its availability.
|
|
1019
|
-
const webResource =
|
|
1020
|
+
const webResource = identityClient.createWebResource(request);
|
|
1020
1021
|
webResource.timeout = (options.requestOptions && options.requestOptions.timeout) || 500;
|
|
1021
1022
|
try {
|
|
1022
|
-
logger$
|
|
1023
|
-
yield
|
|
1023
|
+
logger$7.info(`Pinging IMDS endpoint`);
|
|
1024
|
+
yield identityClient.sendRequest(webResource);
|
|
1024
1025
|
}
|
|
1025
1026
|
catch (err) {
|
|
1026
1027
|
if ((err instanceof coreHttp.RestError && err.code === coreHttp.RestError.REQUEST_SEND_ERROR) ||
|
|
@@ -1030,22 +1031,24 @@ class ManagedIdentityCredential {
|
|
|
1030
1031
|
) {
|
|
1031
1032
|
// If the request failed, or NodeJS was unable to establish a connection,
|
|
1032
1033
|
// or the host was down, we'll assume the IMDS endpoint isn't available.
|
|
1033
|
-
logger$
|
|
1034
|
+
logger$7.info(`IMDS endpoint unavailable`);
|
|
1034
1035
|
span.setStatus({
|
|
1035
1036
|
code: api.CanonicalCode.UNAVAILABLE,
|
|
1036
1037
|
message: err.message
|
|
1037
1038
|
});
|
|
1039
|
+
// IMDS MSI unavailable.
|
|
1038
1040
|
return false;
|
|
1039
1041
|
}
|
|
1040
1042
|
}
|
|
1041
1043
|
// If we received any response, the endpoint is available
|
|
1042
|
-
logger$
|
|
1044
|
+
logger$7.info(`IMDS endpoint is available`);
|
|
1045
|
+
// IMDS MSI available!
|
|
1043
1046
|
return true;
|
|
1044
1047
|
}
|
|
1045
1048
|
catch (err) {
|
|
1046
1049
|
// createWebResource failed.
|
|
1047
1050
|
// This error should bubble up to the user.
|
|
1048
|
-
logger$
|
|
1051
|
+
logger$7.info(`Error when creating the WebResource for the IMDS endpoint: ${err.message}`);
|
|
1049
1052
|
span.setStatus({
|
|
1050
1053
|
code: api.CanonicalCode.UNKNOWN,
|
|
1051
1054
|
message: err.message
|
|
@@ -1056,86 +1059,177 @@ class ManagedIdentityCredential {
|
|
|
1056
1059
|
span.end();
|
|
1057
1060
|
}
|
|
1058
1061
|
});
|
|
1062
|
+
},
|
|
1063
|
+
getToken(identityClient, resource, clientId, getTokenOptions = {}) {
|
|
1064
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1065
|
+
logger$7.info(`Using the IMDS endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
|
|
1066
|
+
return msiGenericGetToken(identityClient, prepareRequestOptions$1(resource, clientId), expiresInParser$1, getTokenOptions);
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
|
|
1071
|
+
// Copyright (c) Microsoft Corporation.
|
|
1072
|
+
const logger$8 = credentialLogger("ManagedIdentityCredential - AppServiceMSI 2017");
|
|
1073
|
+
function expiresInParser$2(requestBody) {
|
|
1074
|
+
// Parse a date format like "06/20/2019 02:57:58 +00:00" and
|
|
1075
|
+
// convert it into a JavaScript-formatted date
|
|
1076
|
+
return Date.parse(requestBody.expires_on);
|
|
1077
|
+
}
|
|
1078
|
+
function prepareRequestOptions$2(resource, clientId) {
|
|
1079
|
+
const queryParameters = {
|
|
1080
|
+
resource,
|
|
1081
|
+
"api-version": "2017-09-01"
|
|
1082
|
+
};
|
|
1083
|
+
if (clientId) {
|
|
1084
|
+
queryParameters.clientid = clientId;
|
|
1059
1085
|
}
|
|
1060
|
-
|
|
1086
|
+
return {
|
|
1087
|
+
url: process.env.MSI_ENDPOINT,
|
|
1088
|
+
method: "GET",
|
|
1089
|
+
queryParameters,
|
|
1090
|
+
headers: {
|
|
1091
|
+
Accept: "application/json",
|
|
1092
|
+
secret: process.env.MSI_SECRET
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
const appServiceMsi2017 = {
|
|
1097
|
+
isAvailable() {
|
|
1098
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1099
|
+
const env = process.env;
|
|
1100
|
+
return Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
|
|
1101
|
+
});
|
|
1102
|
+
},
|
|
1103
|
+
getToken(identityClient, resource, clientId, getTokenOptions = {}) {
|
|
1061
1104
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1105
|
+
logger$8.info(`Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
1106
|
+
return msiGenericGetToken(identityClient, prepareRequestOptions$2(resource, clientId), expiresInParser$2, getTokenOptions);
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
// Copyright (c) Microsoft Corporation.
|
|
1112
|
+
const logger$9 = credentialLogger("ManagedIdentityCredential - ArcMSI");
|
|
1113
|
+
// Azure Arc MSI doesn't have a special expiresIn parser.
|
|
1114
|
+
const expiresInParser$3 = undefined;
|
|
1115
|
+
function prepareRequestOptions$3(resource) {
|
|
1116
|
+
const queryParameters = {
|
|
1117
|
+
resource,
|
|
1118
|
+
"api-version": azureArcAPIVersion
|
|
1119
|
+
};
|
|
1120
|
+
return {
|
|
1121
|
+
// Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
|
|
1122
|
+
url: process.env.IDENTITY_ENDPOINT,
|
|
1123
|
+
method: "GET",
|
|
1124
|
+
queryParameters,
|
|
1125
|
+
headers: {
|
|
1126
|
+
Accept: "application/json",
|
|
1127
|
+
Metadata: true
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
// Since "fs"'s readFileSync locks the thread, and to avoid extra dependencies.
|
|
1132
|
+
function readFileAsync(path, options) {
|
|
1133
|
+
return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
|
|
1134
|
+
if (err) {
|
|
1135
|
+
reject(err);
|
|
1136
|
+
}
|
|
1137
|
+
resolve(data);
|
|
1138
|
+
}));
|
|
1139
|
+
}
|
|
1140
|
+
function filePathRequest(identityClient, requestPrepareOptions) {
|
|
1141
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1142
|
+
const response = yield identityClient.sendRequest(identityClient.createWebResource(requestPrepareOptions));
|
|
1143
|
+
if (response.status !== 401) {
|
|
1144
|
+
let message = "";
|
|
1145
|
+
if (response.bodyAsText) {
|
|
1146
|
+
message = ` Response: ${response.bodyAsText}`;
|
|
1147
|
+
}
|
|
1148
|
+
throw new AuthenticationError(response.status, `To authenticate with Azure Arc MSI, status code 401 is expected on the first request.${message}`);
|
|
1149
|
+
}
|
|
1150
|
+
const authHeader = response.headers.get("www-authenticate") || "";
|
|
1151
|
+
return authHeader.split("=").slice(1)[0];
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
const arcMsi = {
|
|
1155
|
+
isAvailable() {
|
|
1156
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1157
|
+
return Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
|
|
1158
|
+
});
|
|
1159
|
+
},
|
|
1160
|
+
getToken(identityClient, resource, clientId, getTokenOptions = {}) {
|
|
1161
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1162
|
+
logger$9.info(`Using the Azure Arc MSI to authenticate.`);
|
|
1163
|
+
if (clientId) {
|
|
1164
|
+
throw new Error("User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.");
|
|
1165
|
+
}
|
|
1166
|
+
const requestOptions = Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions }, prepareRequestOptions$3(resource));
|
|
1167
|
+
const filePath = yield filePathRequest(identityClient, requestOptions);
|
|
1168
|
+
if (!filePath) {
|
|
1169
|
+
throw new Error("Azure Arc MSI failed to find the token file.");
|
|
1170
|
+
}
|
|
1171
|
+
const key = yield readFileAsync(filePath, { encoding: "utf-8" });
|
|
1172
|
+
requestOptions.headers["Authorization"] = `Basic ${key}`;
|
|
1173
|
+
return msiGenericGetToken(identityClient, requestOptions, expiresInParser$3, getTokenOptions);
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1178
|
+
// Copyright (c) Microsoft Corporation.
|
|
1179
|
+
const logger$a = credentialLogger("ManagedIdentityCredential");
|
|
1180
|
+
/**
|
|
1181
|
+
* Attempts authentication using a managed identity that has been assigned
|
|
1182
|
+
* to the deployment environment. This authentication type works in Azure VMs,
|
|
1183
|
+
* App Service and Azure Functions applications, and inside of Azure Cloud Shell.
|
|
1184
|
+
*
|
|
1185
|
+
* More information about configuring managed identities can be found here:
|
|
1186
|
+
*
|
|
1187
|
+
* https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
|
|
1188
|
+
*/
|
|
1189
|
+
class ManagedIdentityCredential {
|
|
1190
|
+
/**
|
|
1191
|
+
* @internal
|
|
1192
|
+
* @ignore
|
|
1193
|
+
*/
|
|
1194
|
+
constructor(clientIdOrOptions, options) {
|
|
1195
|
+
this.isEndpointUnavailable = null;
|
|
1196
|
+
if (typeof clientIdOrOptions === "string") {
|
|
1197
|
+
// clientId, options constructor
|
|
1198
|
+
this.clientId = clientIdOrOptions;
|
|
1199
|
+
this.identityClient = new IdentityClient(options);
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
// options only constructor
|
|
1203
|
+
this.identityClient = new IdentityClient(clientIdOrOptions);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
cachedAvailableMSI(resource, clientId, getTokenOptions) {
|
|
1207
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1208
|
+
if (this.cachedMSI) {
|
|
1209
|
+
return this.cachedMSI;
|
|
1210
|
+
}
|
|
1211
|
+
// "fabricMsi" can't be added yet because our HTTPs pipeline doesn't allow skipping the SSL verification step,
|
|
1212
|
+
// which is necessary since Service Fabric only provides self-signed certificates on their Identity Endpoint.
|
|
1213
|
+
const MSIs = [appServiceMsi2017, cloudShellMsi, arcMsi, imdsMsi];
|
|
1214
|
+
for (const msi of MSIs) {
|
|
1215
|
+
if (yield msi.isAvailable(this.identityClient, resource, clientId, getTokenOptions)) {
|
|
1216
|
+
this.cachedMSI = msi;
|
|
1217
|
+
return msi;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
throw new CredentialUnavailable("ManagedIdentityCredential - No MSI credential available");
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
authenticateManagedIdentity(scopes, clientId, getTokenOptions) {
|
|
1224
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1225
|
+
const resource = mapScopesToResource(scopes);
|
|
1065
1226
|
const { span, options } = createSpan("ManagedIdentityCredential-authenticateManagedIdentity", getTokenOptions);
|
|
1066
1227
|
try {
|
|
1067
|
-
//
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
authRequestOptions = this.createAppServiceMsiAuthRequest(resource, clientId, "2019-08-01");
|
|
1071
|
-
expiresInParser = (requestBody) => {
|
|
1072
|
-
// Parses a string representation of the seconds since epoch into a number value
|
|
1073
|
-
return Number(requestBody.expires_on);
|
|
1074
|
-
};
|
|
1075
|
-
logger$6.info(`Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
|
1076
|
-
}
|
|
1077
|
-
else if (process.env.MSI_ENDPOINT) {
|
|
1078
|
-
if (process.env.MSI_SECRET) {
|
|
1079
|
-
// Running in App Service
|
|
1080
|
-
authRequestOptions = this.createAppServiceMsiAuthRequest(resource, clientId, "2017-09-01");
|
|
1081
|
-
expiresInParser = (requestBody) => {
|
|
1082
|
-
// Parse a date format like "06/20/2019 02:57:58 +00:00" and
|
|
1083
|
-
// convert it into a JavaScript-formatted date
|
|
1084
|
-
return Date.parse(requestBody.expires_on);
|
|
1085
|
-
};
|
|
1086
|
-
logger$6.info(`Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
1087
|
-
}
|
|
1088
|
-
else {
|
|
1089
|
-
logger$6.info(`Using the endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
|
|
1090
|
-
// Running in Cloud Shell
|
|
1091
|
-
authRequestOptions = this.createCloudShellMsiAuthRequest(resource, clientId);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
else {
|
|
1095
|
-
expiresInParser = (requestBody) => {
|
|
1096
|
-
if (requestBody.expires_on) {
|
|
1097
|
-
// Use the expires_on timestamp if it's available
|
|
1098
|
-
const expires = +requestBody.expires_on * 1000;
|
|
1099
|
-
logger$6.info(`IMDS using expires_on: ${expires} (original value: ${requestBody.expires_on})`);
|
|
1100
|
-
return expires;
|
|
1101
|
-
}
|
|
1102
|
-
else {
|
|
1103
|
-
// If these aren't possible, use expires_in and calculate a timestamp
|
|
1104
|
-
const expires = Date.now() + requestBody.expires_in * 1000;
|
|
1105
|
-
logger$6.info(`IMDS using expires_in: ${expires} (original value: ${requestBody.expires_in})`);
|
|
1106
|
-
return expires;
|
|
1107
|
-
}
|
|
1108
|
-
};
|
|
1109
|
-
logger$6.info(`Using the IMDS endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
|
|
1110
|
-
// Ping the IMDS endpoint to see if it's available
|
|
1111
|
-
if (!checkIfImdsEndpointAvailable ||
|
|
1112
|
-
(yield this.pingImdsEndpoint(resource, clientId, options))) {
|
|
1113
|
-
// Running in an Azure VM
|
|
1114
|
-
authRequestOptions = this.createImdsAuthRequest(resource, clientId);
|
|
1115
|
-
}
|
|
1116
|
-
else {
|
|
1117
|
-
// Returning null tells the ManagedIdentityCredential that
|
|
1118
|
-
// no MSI authentication endpoints are available
|
|
1119
|
-
return null;
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
const webResource = this.identityClient.createWebResource(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: options.abortSignal, spanOptions: options.tracingOptions && options.tracingOptions.spanOptions }, authRequestOptions));
|
|
1123
|
-
const tokenResponse = yield this.identityClient.sendTokenRequest(webResource, expiresInParser);
|
|
1124
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1228
|
+
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
|
|
1229
|
+
const availableMSI = yield this.cachedAvailableMSI(resource, clientId, options);
|
|
1230
|
+
return availableMSI.getToken(this.identityClient, resource, clientId, options);
|
|
1125
1231
|
}
|
|
1126
1232
|
catch (err) {
|
|
1127
|
-
// Expected errors to reach this point:
|
|
1128
|
-
// - When we try call createWebResource and it fails (at any point).
|
|
1129
|
-
// - When identityClient.sendTokenRequest throws.
|
|
1130
|
-
// If the status code was 400, it means that the endpoint is working,
|
|
1131
|
-
// but no identity is available.
|
|
1132
|
-
//
|
|
1133
|
-
// Errors that might reach this point, but shouldn't:
|
|
1134
|
-
// - When createAppServiceMsiAuthRequest is called with an unsupported version.
|
|
1135
|
-
// We shouldn't see this happening, because we specify the version in the parameters.
|
|
1136
|
-
//
|
|
1137
|
-
// Errors that shouldn't reach this point at all:
|
|
1138
|
-
// - If we tried to reach to the IMDS endpoint and it ends up being unavailable, we simply don't call to createImdsAuthRequest, so we return null.
|
|
1139
1233
|
const code = err.name === AuthenticationErrorName
|
|
1140
1234
|
? api.CanonicalCode.UNAUTHENTICATED
|
|
1141
1235
|
: api.CanonicalCode.UNKNOWN;
|
|
@@ -1169,7 +1263,7 @@ class ManagedIdentityCredential {
|
|
|
1169
1263
|
// If it's null, it means we don't yet know whether
|
|
1170
1264
|
// the endpoint is available and need to check for it.
|
|
1171
1265
|
if (this.isEndpointUnavailable !== true) {
|
|
1172
|
-
result = yield this.authenticateManagedIdentity(scopes, this.
|
|
1266
|
+
result = yield this.authenticateManagedIdentity(scopes, this.clientId, newOptions);
|
|
1173
1267
|
if (result === null) {
|
|
1174
1268
|
// If authenticateManagedIdentity returns null,
|
|
1175
1269
|
// it means no MSI endpoints are available.
|
|
@@ -1178,35 +1272,22 @@ class ManagedIdentityCredential {
|
|
|
1178
1272
|
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
|
|
1179
1273
|
// yet we had no access token. For this reason, we'll throw once with a specific message:
|
|
1180
1274
|
const error = new CredentialUnavailable("The managed identity endpoint was reached, yet no tokens were received.");
|
|
1181
|
-
logger$
|
|
1275
|
+
logger$a.getToken.info(formatError(scopes, error));
|
|
1182
1276
|
throw error;
|
|
1183
1277
|
}
|
|
1184
1278
|
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
|
|
1185
1279
|
// We will assume that this endpoint is reachable from this point forward,
|
|
1186
1280
|
// and avoid pinging again to it.
|
|
1187
|
-
// Details:
|
|
1188
|
-
// - If `isEndpointUnavailable` is not true, `authenticateManagedIdentity` is called.
|
|
1189
|
-
// - If `isEndpointUnavailable` is only set to false if `authenticateManagedIdentity` returns null.
|
|
1190
|
-
// - If `isEndpointUnavailable` is null, `authenticateManagedIdentity` wil be called with "true" as the second parameter.
|
|
1191
|
-
// - When `authenticateManagedIdentity` is called with `checkIfImdsEndpointAvailable` set to "true", `pingImdsEndpoint` is called.
|
|
1192
|
-
// - If `pingImdsEndpoint` returns false, `authenticateManagedIdentity` returns null, which sets `isEndpointUnavailable` to false.
|
|
1193
|
-
// - If `pingImdsEndpoint` returns true, `authenticateManagedIdentity` tries to authenticate with the IMDS endpoint.
|
|
1194
|
-
// - If `authenticateManagedIdentity` tries to authenticate, and throws, we move to the catch section of this function.
|
|
1195
|
-
// - If `authenticateManagedIdentity` manages to authenticate, `result` won't be null.
|
|
1196
|
-
// - If `result` isn't null at this point, the endpoint was in fact available at first.
|
|
1197
|
-
// - To avoid calling again to `pingImdsEndpoint`, we need to set `isEndpointUnavailable` to false,
|
|
1198
|
-
// so that `authenticateManagedIdentity` gets to be called with `checkIfImdsEndpointAvailable` set to "false",
|
|
1199
|
-
// thus skipping any further call to `pingImdsEndpoint`.
|
|
1200
1281
|
this.isEndpointUnavailable = false;
|
|
1201
1282
|
}
|
|
1202
1283
|
else {
|
|
1203
1284
|
// We've previously determined that the endpoint was unavailable,
|
|
1204
1285
|
// either because it was unreachable or permanently unable to authenticate.
|
|
1205
1286
|
const error = new CredentialUnavailable("The managed identity endpoint is not currently available");
|
|
1206
|
-
logger$
|
|
1287
|
+
logger$a.getToken.info(formatError(scopes, error));
|
|
1207
1288
|
throw error;
|
|
1208
1289
|
}
|
|
1209
|
-
logger$
|
|
1290
|
+
logger$a.getToken.info(formatSuccess(scopes));
|
|
1210
1291
|
return result;
|
|
1211
1292
|
}
|
|
1212
1293
|
catch (err) {
|
|
@@ -1226,7 +1307,7 @@ class ManagedIdentityCredential {
|
|
|
1226
1307
|
});
|
|
1227
1308
|
if (err.code === "ENETUNREACH") {
|
|
1228
1309
|
const error = new CredentialUnavailable("ManagedIdentityCredential is unavailable. No managed identity endpoint found.");
|
|
1229
|
-
logger$
|
|
1310
|
+
logger$a.getToken.info(formatError(scopes, error));
|
|
1230
1311
|
throw error;
|
|
1231
1312
|
}
|
|
1232
1313
|
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
|
@@ -1259,7 +1340,7 @@ function getSafeWorkingDir() {
|
|
|
1259
1340
|
return "/bin";
|
|
1260
1341
|
}
|
|
1261
1342
|
}
|
|
1262
|
-
const logger$
|
|
1343
|
+
const logger$b = credentialLogger("AzureCliCredential");
|
|
1263
1344
|
/**
|
|
1264
1345
|
* This credential will use the currently logged-in user login information
|
|
1265
1346
|
* via the Azure CLI ('az') commandline tool.
|
|
@@ -1301,12 +1382,12 @@ class AzureCliCredential {
|
|
|
1301
1382
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1302
1383
|
return new Promise((resolve, reject) => {
|
|
1303
1384
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
1304
|
-
logger$
|
|
1385
|
+
logger$b.getToken.info(`Using the scope ${scope}`);
|
|
1305
1386
|
const resource = scope.replace(/\/.default$/, "");
|
|
1306
1387
|
// Check to make sure the scope we get back is a valid scope
|
|
1307
1388
|
if (!scope.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
1308
1389
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
1309
|
-
logger$
|
|
1390
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
1310
1391
|
throw error;
|
|
1311
1392
|
}
|
|
1312
1393
|
let responseData = "";
|
|
@@ -1319,22 +1400,22 @@ class AzureCliCredential {
|
|
|
1319
1400
|
obj.stderr.startsWith("'az' is not recognized");
|
|
1320
1401
|
if (isNotInstallError) {
|
|
1321
1402
|
const error = new CredentialUnavailable("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");
|
|
1322
|
-
logger$
|
|
1403
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
1323
1404
|
throw error;
|
|
1324
1405
|
}
|
|
1325
1406
|
else if (isLoginError) {
|
|
1326
1407
|
const error = new CredentialUnavailable("Please run 'az login' from a command prompt to authenticate before using this credential.");
|
|
1327
|
-
logger$
|
|
1408
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
1328
1409
|
throw error;
|
|
1329
1410
|
}
|
|
1330
1411
|
const error = new CredentialUnavailable(obj.stderr);
|
|
1331
|
-
logger$
|
|
1412
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
1332
1413
|
throw error;
|
|
1333
1414
|
}
|
|
1334
1415
|
else {
|
|
1335
1416
|
responseData = obj.stdout;
|
|
1336
1417
|
const response = JSON.parse(responseData);
|
|
1337
|
-
logger$
|
|
1418
|
+
logger$b.getToken.info(formatSuccess(scopes));
|
|
1338
1419
|
const returnValue = {
|
|
1339
1420
|
token: response.accessToken,
|
|
1340
1421
|
expiresOnTimestamp: new Date(response.expiresOn).getTime()
|
|
@@ -1351,7 +1432,7 @@ class AzureCliCredential {
|
|
|
1351
1432
|
code,
|
|
1352
1433
|
message: err.message
|
|
1353
1434
|
});
|
|
1354
|
-
logger$
|
|
1435
|
+
logger$b.getToken.info(formatError(scopes, err));
|
|
1355
1436
|
reject(err);
|
|
1356
1437
|
});
|
|
1357
1438
|
});
|
|
@@ -1359,6 +1440,42 @@ class AzureCliCredential {
|
|
|
1359
1440
|
}
|
|
1360
1441
|
}
|
|
1361
1442
|
|
|
1443
|
+
// Copyright (c) Microsoft Corporation.
|
|
1444
|
+
// Licensed under the MIT license.
|
|
1445
|
+
/**
|
|
1446
|
+
* The default client ID for authentication
|
|
1447
|
+
* @internal
|
|
1448
|
+
* @ignore
|
|
1449
|
+
*/
|
|
1450
|
+
// TODO: temporary - this is the Azure CLI clientID - we'll replace it when
|
|
1451
|
+
// Developer Sign On application is available
|
|
1452
|
+
// https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/src/Constants.cs#L9
|
|
1453
|
+
const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
|
|
1454
|
+
/**
|
|
1455
|
+
* The default tenant for authentication
|
|
1456
|
+
* @internal
|
|
1457
|
+
* @ignore
|
|
1458
|
+
*/
|
|
1459
|
+
const DefaultTenantId = "common";
|
|
1460
|
+
(function (AzureAuthorityHosts) {
|
|
1461
|
+
/**
|
|
1462
|
+
* China-based Azure Authority Host
|
|
1463
|
+
*/
|
|
1464
|
+
AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
|
|
1465
|
+
/**
|
|
1466
|
+
* Germany-based Azure Authority Host
|
|
1467
|
+
*/
|
|
1468
|
+
AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
|
|
1469
|
+
/**
|
|
1470
|
+
* US Government Azure Authority Host
|
|
1471
|
+
*/
|
|
1472
|
+
AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
|
|
1473
|
+
/**
|
|
1474
|
+
* Public Cloud Azure Authority Host
|
|
1475
|
+
*/
|
|
1476
|
+
AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
|
|
1477
|
+
})(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
|
|
1478
|
+
|
|
1362
1479
|
// Copyright (c) Microsoft Corporation.
|
|
1363
1480
|
let keytar;
|
|
1364
1481
|
try {
|
|
@@ -1370,7 +1487,7 @@ catch (er) {
|
|
|
1370
1487
|
const CommonTenantId = "common";
|
|
1371
1488
|
const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
|
|
1372
1489
|
const VSCodeUserName = "VS Code Azure";
|
|
1373
|
-
const logger$
|
|
1490
|
+
const logger$c = credentialLogger("VisualStudioCodeCredential");
|
|
1374
1491
|
// Map of unsupported Tenant IDs and the errors we will be throwing.
|
|
1375
1492
|
const unsupportedTenantIds = {
|
|
1376
1493
|
adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants."
|
|
@@ -1382,6 +1499,12 @@ function checkUnsupportedTenant(tenantId) {
|
|
|
1382
1499
|
throw new CredentialUnavailable(unsupportedTenantError);
|
|
1383
1500
|
}
|
|
1384
1501
|
}
|
|
1502
|
+
const mapVSCodeAuthorityHosts = {
|
|
1503
|
+
AzureCloud: exports.AzureAuthorityHosts.AzurePublicCloud,
|
|
1504
|
+
AzureChina: exports.AzureAuthorityHosts.AzureChina,
|
|
1505
|
+
AzureGermanCloud: exports.AzureAuthorityHosts.AzureGermany,
|
|
1506
|
+
AzureUSGovernment: exports.AzureAuthorityHosts.AzureGovernment
|
|
1507
|
+
};
|
|
1385
1508
|
/**
|
|
1386
1509
|
* Attempts to load a specific property from the VSCode configurations of the current OS.
|
|
1387
1510
|
* If it fails at any point, returns undefined.
|
|
@@ -1411,7 +1534,7 @@ function getPropertyFromVSCode(property) {
|
|
|
1411
1534
|
}
|
|
1412
1535
|
}
|
|
1413
1536
|
catch (e) {
|
|
1414
|
-
logger$
|
|
1537
|
+
logger$c.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
|
|
1415
1538
|
return;
|
|
1416
1539
|
}
|
|
1417
1540
|
}
|
|
@@ -1427,8 +1550,14 @@ class VisualStudioCodeCredential {
|
|
|
1427
1550
|
* @param options Options for configuring the client which makes the authentication request.
|
|
1428
1551
|
*/
|
|
1429
1552
|
constructor(options) {
|
|
1430
|
-
|
|
1553
|
+
// We want to make sure we use the one assigned by the user on the VSCode settings.
|
|
1554
|
+
// Or just `AzureCloud` by default.
|
|
1555
|
+
this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud");
|
|
1556
|
+
// Picking an authority host based on the cloud name.
|
|
1557
|
+
const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
|
|
1558
|
+
this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
|
|
1431
1559
|
if (options && options.tenantId) {
|
|
1560
|
+
checkTenantId(logger$c, options.tenantId);
|
|
1432
1561
|
this.tenantId = options.tenantId;
|
|
1433
1562
|
}
|
|
1434
1563
|
else {
|
|
@@ -1477,7 +1606,7 @@ class VisualStudioCodeCredential {
|
|
|
1477
1606
|
// Check to make sure the scope we get back is a valid scope
|
|
1478
1607
|
if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
1479
1608
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
1480
|
-
logger$
|
|
1609
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
1481
1610
|
throw error;
|
|
1482
1611
|
}
|
|
1483
1612
|
if (scopeString.indexOf("offline_access") < 0) {
|
|
@@ -1492,11 +1621,8 @@ class VisualStudioCodeCredential {
|
|
|
1492
1621
|
// /* ... */
|
|
1493
1622
|
// ]
|
|
1494
1623
|
const credentials = yield keytar.findCredentials(VSCodeUserName);
|
|
1495
|
-
// We want to make sure we use the one assigned by the user on the VSCode settings.
|
|
1496
|
-
// Or just `Azure` by default.
|
|
1497
|
-
const cloudName = getPropertyFromVSCode("azure.cloud") || "Azure";
|
|
1498
1624
|
// If we can't find the credential based on the name, we'll pick the first one available.
|
|
1499
|
-
const { password } = credentials.find((cred) => cred.account === cloudName) ||
|
|
1625
|
+
const { password } = credentials.find((cred) => cred.account === this.cloudName) ||
|
|
1500
1626
|
credentials[0] ||
|
|
1501
1627
|
{};
|
|
1502
1628
|
// Assuming we found something, the refresh token is the "password" property.
|
|
@@ -1504,18 +1630,18 @@ class VisualStudioCodeCredential {
|
|
|
1504
1630
|
if (refreshToken) {
|
|
1505
1631
|
const tokenResponse = yield this.identityClient.refreshAccessToken(this.tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
|
|
1506
1632
|
if (tokenResponse) {
|
|
1507
|
-
logger$
|
|
1633
|
+
logger$c.getToken.info(formatSuccess(scopes));
|
|
1508
1634
|
return tokenResponse.accessToken;
|
|
1509
1635
|
}
|
|
1510
1636
|
else {
|
|
1511
1637
|
const error = new CredentialUnavailable("Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently?");
|
|
1512
|
-
logger$
|
|
1638
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
1513
1639
|
throw error;
|
|
1514
1640
|
}
|
|
1515
1641
|
}
|
|
1516
1642
|
else {
|
|
1517
1643
|
const error = new CredentialUnavailable("Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension?");
|
|
1518
|
-
logger$
|
|
1644
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
1519
1645
|
throw error;
|
|
1520
1646
|
}
|
|
1521
1647
|
});
|
|
@@ -1556,40 +1682,84 @@ class DefaultAzureCredential extends ChainedTokenCredential {
|
|
|
1556
1682
|
}
|
|
1557
1683
|
|
|
1558
1684
|
// Copyright (c) Microsoft Corporation.
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1685
|
+
const logger$d = credentialLogger("InteractiveBrowserCredential");
|
|
1686
|
+
class AuthenticationRequired extends CredentialUnavailable {
|
|
1687
|
+
}
|
|
1688
|
+
class MsalClient {
|
|
1689
|
+
constructor(msalConfig, persistenceEnabled, authenticationRecord, options) {
|
|
1690
|
+
this.identityClient = new IdentityClient(options);
|
|
1691
|
+
this.msalConfig = msalConfig;
|
|
1692
|
+
this.persistenceEnabled = persistenceEnabled;
|
|
1693
|
+
this.authenticationRecord = authenticationRecord;
|
|
1694
|
+
}
|
|
1695
|
+
prepareClientApplications() {
|
|
1696
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1697
|
+
// If we've already initialized the public client application, return
|
|
1698
|
+
if (this.pca) {
|
|
1699
|
+
return;
|
|
1700
|
+
}
|
|
1701
|
+
// Construct the public client application, since it hasn't been initialized, yet
|
|
1702
|
+
const clientConfig = {
|
|
1703
|
+
auth: this.msalConfig,
|
|
1704
|
+
cache: undefined,
|
|
1705
|
+
system: { networkClient: this.identityClient }
|
|
1706
|
+
};
|
|
1707
|
+
this.pca = new msalNode.PublicClientApplication(clientConfig);
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
acquireTokenFromCache(scopes) {
|
|
1711
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1712
|
+
yield this.prepareClientApplications();
|
|
1713
|
+
if (!this.persistenceEnabled || !this.authenticationRecord) {
|
|
1714
|
+
throw new AuthenticationRequired();
|
|
1715
|
+
}
|
|
1716
|
+
const silentRequest = {
|
|
1717
|
+
account: this.authenticationRecord,
|
|
1718
|
+
scopes
|
|
1719
|
+
};
|
|
1720
|
+
try {
|
|
1721
|
+
const response = yield this.pca.acquireTokenSilent(silentRequest);
|
|
1722
|
+
logger$d.info("Successful silent token acquisition");
|
|
1723
|
+
return {
|
|
1724
|
+
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
1725
|
+
token: response.accessToken
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
catch (e) {
|
|
1729
|
+
throw new AuthenticationRequired("Could not authenticate silently using the cache");
|
|
1730
|
+
}
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
getAuthCodeUrl(request) {
|
|
1734
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1735
|
+
yield this.prepareClientApplications();
|
|
1736
|
+
return this.pca.getAuthCodeUrl(request);
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
acquireTokenByCode(request) {
|
|
1740
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1741
|
+
yield this.prepareClientApplications();
|
|
1742
|
+
return this.pca.acquireTokenByCode(request);
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
acquireTokenByDeviceCode(request) {
|
|
1746
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1747
|
+
yield this.prepareClientApplications();
|
|
1748
|
+
return this.pca.acquireTokenByDeviceCode(request);
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
acquireTokenByClientCredential(request) {
|
|
1752
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1753
|
+
yield this.prepareClientApplications();
|
|
1754
|
+
return this.cca.acquireTokenByClientCredential(request);
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
var HttpMethod;
|
|
1759
|
+
(function (HttpMethod) {
|
|
1760
|
+
HttpMethod["GET"] = "get";
|
|
1761
|
+
HttpMethod["POST"] = "post";
|
|
1762
|
+
})(HttpMethod || (HttpMethod = {}));
|
|
1593
1763
|
|
|
1594
1764
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
1595
1765
|
|
|
@@ -41113,9 +41283,7 @@ var express_10 = express.urlencoded;
|
|
|
41113
41283
|
var express$1 = express;
|
|
41114
41284
|
|
|
41115
41285
|
// Copyright (c) Microsoft Corporation.
|
|
41116
|
-
const logger$
|
|
41117
|
-
class AuthenticationRequired extends CredentialUnavailable {
|
|
41118
|
-
}
|
|
41286
|
+
const logger$e = credentialLogger("InteractiveBrowserCredential");
|
|
41119
41287
|
/**
|
|
41120
41288
|
* Enables authentication to Azure Active Directory inside of the web browser
|
|
41121
41289
|
* using the interactive login flow, either via browser redirects or a popup
|
|
@@ -41123,12 +41291,11 @@ class AuthenticationRequired extends CredentialUnavailable {
|
|
|
41123
41291
|
*/
|
|
41124
41292
|
class InteractiveBrowserCredential {
|
|
41125
41293
|
constructor(options) {
|
|
41126
|
-
|
|
41127
|
-
|
|
41128
|
-
|
|
41129
|
-
//
|
|
41130
|
-
|
|
41131
|
-
this.authenticationRecord = options === null || options === void 0 ? void 0 : options.authenticationRecord;
|
|
41294
|
+
const tenantId = (options && options.tenantId) || DefaultTenantId;
|
|
41295
|
+
const clientId = (options && options.clientId) || DeveloperSignOnClientId;
|
|
41296
|
+
checkTenantId(logger$e, tenantId);
|
|
41297
|
+
// const persistenceEnabled = options?.persistenceEnabled ? options?.persistenceEnabled : false;
|
|
41298
|
+
// const authenticationRecord = options?.authenticationRecord;
|
|
41132
41299
|
if (options && options.redirectUri) {
|
|
41133
41300
|
if (typeof options.redirectUri === "string") {
|
|
41134
41301
|
this.redirectUri = options.redirectUri;
|
|
@@ -41145,29 +41312,19 @@ class InteractiveBrowserCredential {
|
|
|
41145
41312
|
if (isNaN(this.port)) {
|
|
41146
41313
|
this.port = 80;
|
|
41147
41314
|
}
|
|
41315
|
+
let authorityHost;
|
|
41148
41316
|
if (options && options.authorityHost) {
|
|
41149
41317
|
if (options.authorityHost.endsWith("/")) {
|
|
41150
|
-
|
|
41318
|
+
authorityHost = options.authorityHost + tenantId;
|
|
41151
41319
|
}
|
|
41152
41320
|
else {
|
|
41153
|
-
|
|
41321
|
+
authorityHost = options.authorityHost + "/" + tenantId;
|
|
41154
41322
|
}
|
|
41155
41323
|
}
|
|
41156
41324
|
else {
|
|
41157
|
-
|
|
41325
|
+
authorityHost = "https://login.microsoftonline.com/" + tenantId;
|
|
41158
41326
|
}
|
|
41159
|
-
|
|
41160
|
-
const publicClientConfig = {
|
|
41161
|
-
auth: {
|
|
41162
|
-
clientId: this.clientId,
|
|
41163
|
-
authority: this.authorityHost,
|
|
41164
|
-
knownAuthorities: knownAuthorities
|
|
41165
|
-
},
|
|
41166
|
-
cache: options === null || options === void 0 ? void 0 : options.cacheOptions,
|
|
41167
|
-
system: { networkClient: this.identityClient }
|
|
41168
|
-
};
|
|
41169
|
-
this.pca = new msalNode.PublicClientApplication(publicClientConfig);
|
|
41170
|
-
this.msalCacheManager = this.pca.getTokenCache();
|
|
41327
|
+
this.msalClient = new MsalClient({ clientId, authority: authorityHost }, false, undefined, options);
|
|
41171
41328
|
}
|
|
41172
41329
|
/**
|
|
41173
41330
|
* Authenticates with Azure Active Directory and returns an access token if
|
|
@@ -41181,37 +41338,13 @@ class InteractiveBrowserCredential {
|
|
|
41181
41338
|
*/
|
|
41182
41339
|
getToken(scopes, _options) {
|
|
41183
41340
|
const scopeArray = typeof scopes === "object" ? scopes : [scopes];
|
|
41184
|
-
|
|
41185
|
-
|
|
41186
|
-
|
|
41187
|
-
return this.acquireTokenFromBrowser(scopeArray);
|
|
41188
|
-
}
|
|
41189
|
-
else {
|
|
41190
|
-
throw e;
|
|
41191
|
-
}
|
|
41192
|
-
});
|
|
41193
|
-
}
|
|
41194
|
-
else {
|
|
41195
|
-
return this.acquireTokenFromBrowser(scopeArray);
|
|
41196
|
-
}
|
|
41197
|
-
}
|
|
41198
|
-
acquireTokenFromCache() {
|
|
41199
|
-
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
41200
|
-
yield this.msalCacheManager.readFromPersistence();
|
|
41201
|
-
const silentRequest = {
|
|
41202
|
-
account: this.authenticationRecord,
|
|
41203
|
-
scopes: ["https://vault.azure.net/user_impersonation", "https://vault.azure.net/.default"]
|
|
41204
|
-
};
|
|
41205
|
-
try {
|
|
41206
|
-
const response = yield this.pca.acquireTokenSilent(silentRequest);
|
|
41207
|
-
logger$9.info("Successful silent token acquisition");
|
|
41208
|
-
return {
|
|
41209
|
-
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
41210
|
-
token: response.accessToken
|
|
41211
|
-
};
|
|
41341
|
+
return this.msalClient.acquireTokenFromCache(scopeArray).catch((e) => {
|
|
41342
|
+
if (e instanceof AuthenticationRequired) {
|
|
41343
|
+
return this.acquireTokenFromBrowser(scopeArray);
|
|
41212
41344
|
}
|
|
41213
|
-
|
|
41214
|
-
|
|
41345
|
+
else {
|
|
41346
|
+
logger$e.getToken.info(formatError(scopes, e));
|
|
41347
|
+
throw e;
|
|
41215
41348
|
}
|
|
41216
41349
|
});
|
|
41217
41350
|
}
|
|
@@ -41221,11 +41354,8 @@ class InteractiveBrowserCredential {
|
|
|
41221
41354
|
scopes: scopeArray,
|
|
41222
41355
|
redirectUri: this.redirectUri
|
|
41223
41356
|
};
|
|
41224
|
-
const response = yield this.
|
|
41357
|
+
const response = yield this.msalClient.getAuthCodeUrl(authCodeUrlParameters);
|
|
41225
41358
|
yield open(response);
|
|
41226
|
-
if (this.persistenceEnabled) {
|
|
41227
|
-
yield this.msalCacheManager.readFromPersistence();
|
|
41228
|
-
}
|
|
41229
41359
|
});
|
|
41230
41360
|
}
|
|
41231
41361
|
acquireTokenFromBrowser(scopeArray) {
|
|
@@ -41252,25 +41382,27 @@ class InteractiveBrowserCredential {
|
|
|
41252
41382
|
scopes: scopeArray
|
|
41253
41383
|
};
|
|
41254
41384
|
try {
|
|
41255
|
-
const authResponse = yield this.
|
|
41256
|
-
|
|
41257
|
-
|
|
41258
|
-
|
|
41259
|
-
|
|
41385
|
+
const authResponse = yield this.msalClient.acquireTokenByCode(tokenRequest);
|
|
41386
|
+
const successMessage = `Authentication Complete. You can close the browser and return to the application.`;
|
|
41387
|
+
const expiresOnTimestamp = authResponse === null || authResponse === void 0 ? void 0 : authResponse.expiresOn.valueOf();
|
|
41388
|
+
res.status(200).send(successMessage);
|
|
41389
|
+
logger$e.getToken.info(formatSuccess(scopeArray));
|
|
41260
41390
|
resolve({
|
|
41261
|
-
expiresOnTimestamp
|
|
41391
|
+
expiresOnTimestamp,
|
|
41262
41392
|
token: authResponse.accessToken
|
|
41263
41393
|
});
|
|
41264
41394
|
}
|
|
41265
41395
|
catch (error) {
|
|
41266
|
-
|
|
41267
|
-
|
|
41396
|
+
const errorMessage = formatError(scopeArray, `${req.query["error"]}. ${req.query["error_description"]}`);
|
|
41397
|
+
res.status(500).send(errorMessage);
|
|
41398
|
+
logger$e.getToken.info(errorMessage);
|
|
41399
|
+
reject(new Error(errorMessage));
|
|
41268
41400
|
}
|
|
41269
41401
|
finally {
|
|
41270
41402
|
cleanup();
|
|
41271
41403
|
}
|
|
41272
41404
|
}));
|
|
41273
|
-
listen = app.listen(this.port, () => logger$
|
|
41405
|
+
listen = app.listen(this.port, () => logger$e.info(`Msal Node Auth Code Sample app listening on port ${this.port}!`));
|
|
41274
41406
|
listen.on("connection", (socket) => (socketToDestroy = socket));
|
|
41275
41407
|
try {
|
|
41276
41408
|
yield this.openAuthCodeUrl(scopeArray);
|
|
@@ -41284,7 +41416,7 @@ class InteractiveBrowserCredential {
|
|
|
41284
41416
|
}
|
|
41285
41417
|
}
|
|
41286
41418
|
|
|
41287
|
-
const logger$
|
|
41419
|
+
const logger$f = credentialLogger("DeviceCodeCredential");
|
|
41288
41420
|
/**
|
|
41289
41421
|
* Method that logs the user code from the DeviceCodeCredential.
|
|
41290
41422
|
* @param deviceCodeInfo The device code.
|
|
@@ -41302,39 +41434,30 @@ class DeviceCodeCredential {
|
|
|
41302
41434
|
* to initiate the device code authorization flow with Azure Active Directory.
|
|
41303
41435
|
*
|
|
41304
41436
|
* @param tenantId The Azure Active Directory tenant (directory) ID or name.
|
|
41437
|
+
* The default value is 'organizations'.
|
|
41305
41438
|
* 'organizations' may be used when dealing with multi-tenant scenarios.
|
|
41306
41439
|
* @param clientId The client (application) ID of an App Registration in the tenant.
|
|
41440
|
+
* By default we will try to use the Azure CLI's client ID to authenticate.
|
|
41307
41441
|
* @param userPromptCallback A callback function that will be invoked to show
|
|
41308
41442
|
{@link DeviceCodeInfo} to the user. If left unassigned, we will automatically log the device code information and the authentication instructions in the console.
|
|
41309
41443
|
* @param options Options for configuring the client which makes the authentication request.
|
|
41310
41444
|
*/
|
|
41311
|
-
constructor(tenantId, clientId, userPromptCallback = defaultDeviceCodePromptCallback, options) {
|
|
41312
|
-
|
|
41313
|
-
this.clientId = clientId;
|
|
41445
|
+
constructor(tenantId = "organizations", clientId = DeveloperSignOnClientId, userPromptCallback = defaultDeviceCodePromptCallback, options) {
|
|
41446
|
+
checkTenantId(logger$f, tenantId);
|
|
41314
41447
|
this.userPromptCallback = userPromptCallback;
|
|
41448
|
+
let authorityHost;
|
|
41315
41449
|
if (options && options.authorityHost) {
|
|
41316
41450
|
if (options.authorityHost.endsWith("/")) {
|
|
41317
|
-
|
|
41451
|
+
authorityHost = options.authorityHost + tenantId;
|
|
41318
41452
|
}
|
|
41319
41453
|
else {
|
|
41320
|
-
|
|
41454
|
+
authorityHost = options.authorityHost + "/" + tenantId;
|
|
41321
41455
|
}
|
|
41322
41456
|
}
|
|
41323
41457
|
else {
|
|
41324
|
-
|
|
41458
|
+
authorityHost = "https://login.microsoftonline.com/" + tenantId;
|
|
41325
41459
|
}
|
|
41326
|
-
|
|
41327
|
-
const publicClientConfig = {
|
|
41328
|
-
auth: {
|
|
41329
|
-
clientId: this.clientId,
|
|
41330
|
-
authority: this.authorityHost,
|
|
41331
|
-
knownAuthorities: knownAuthorities
|
|
41332
|
-
},
|
|
41333
|
-
cache: {
|
|
41334
|
-
cachePlugin: undefined
|
|
41335
|
-
}
|
|
41336
|
-
};
|
|
41337
|
-
this.pca = new msalNode.PublicClientApplication(publicClientConfig);
|
|
41460
|
+
this.msalClient = new MsalClient({ clientId: clientId, authority: authorityHost }, false, undefined, options);
|
|
41338
41461
|
}
|
|
41339
41462
|
/**
|
|
41340
41463
|
* Authenticates with Azure Active Directory and returns an access token if
|
|
@@ -41347,37 +41470,50 @@ class DeviceCodeCredential {
|
|
|
41347
41470
|
* TokenCredential implementation might make.
|
|
41348
41471
|
*/
|
|
41349
41472
|
getToken(scopes, options) {
|
|
41350
|
-
|
|
41351
|
-
|
|
41352
|
-
|
|
41353
|
-
|
|
41354
|
-
|
|
41355
|
-
|
|
41356
|
-
|
|
41357
|
-
|
|
41358
|
-
return this.
|
|
41359
|
-
|
|
41360
|
-
|
|
41361
|
-
|
|
41362
|
-
|
|
41363
|
-
|
|
41364
|
-
|
|
41365
|
-
|
|
41366
|
-
|
|
41367
|
-
|
|
41368
|
-
|
|
41369
|
-
|
|
41370
|
-
|
|
41371
|
-
|
|
41372
|
-
|
|
41373
|
-
|
|
41473
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
41474
|
+
const { span } = createSpan("DeviceCodeCredential-getToken", options);
|
|
41475
|
+
const scopeArray = typeof scopes === "object" ? scopes : [scopes];
|
|
41476
|
+
const deviceCodeRequest = {
|
|
41477
|
+
deviceCodeCallback: this.userPromptCallback,
|
|
41478
|
+
scopes: scopeArray
|
|
41479
|
+
};
|
|
41480
|
+
logger$f.info(`DeviceCodeCredential invoked. Scopes: ${scopeArray.join(", ")}`);
|
|
41481
|
+
return this.msalClient.acquireTokenFromCache(scopeArray).catch((e) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
41482
|
+
if (e instanceof AuthenticationRequired) {
|
|
41483
|
+
try {
|
|
41484
|
+
const token = yield this.acquireTokenByDeviceCode(deviceCodeRequest, scopeArray);
|
|
41485
|
+
logger$f.getToken.info(formatSuccess(scopeArray));
|
|
41486
|
+
return token;
|
|
41487
|
+
}
|
|
41488
|
+
catch (err) {
|
|
41489
|
+
const code = err.name === AuthenticationErrorName
|
|
41490
|
+
? api.CanonicalCode.UNAUTHENTICATED
|
|
41491
|
+
: api.CanonicalCode.UNKNOWN;
|
|
41492
|
+
span.setStatus({
|
|
41493
|
+
code,
|
|
41494
|
+
message: err.message
|
|
41495
|
+
});
|
|
41496
|
+
logger$f.getToken.info(formatError(scopeArray, err));
|
|
41497
|
+
throw err;
|
|
41498
|
+
}
|
|
41499
|
+
finally {
|
|
41500
|
+
span.end();
|
|
41501
|
+
}
|
|
41502
|
+
}
|
|
41503
|
+
else {
|
|
41504
|
+
throw e;
|
|
41505
|
+
}
|
|
41506
|
+
}));
|
|
41507
|
+
});
|
|
41374
41508
|
}
|
|
41375
|
-
acquireTokenByDeviceCode(deviceCodeRequest) {
|
|
41509
|
+
acquireTokenByDeviceCode(deviceCodeRequest, scopes) {
|
|
41376
41510
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
41377
41511
|
try {
|
|
41378
|
-
const deviceResponse = yield this.
|
|
41512
|
+
const deviceResponse = yield this.msalClient.acquireTokenByDeviceCode(deviceCodeRequest);
|
|
41513
|
+
const expiresOnTimestamp = deviceResponse.expiresOn.getTime();
|
|
41514
|
+
logger$f.getToken.info(formatSuccess(scopes));
|
|
41379
41515
|
return {
|
|
41380
|
-
expiresOnTimestamp
|
|
41516
|
+
expiresOnTimestamp,
|
|
41381
41517
|
token: deviceResponse.accessToken
|
|
41382
41518
|
};
|
|
41383
41519
|
}
|
|
@@ -41389,7 +41525,7 @@ class DeviceCodeCredential {
|
|
|
41389
41525
|
}
|
|
41390
41526
|
|
|
41391
41527
|
// Copyright (c) Microsoft Corporation.
|
|
41392
|
-
const logger$
|
|
41528
|
+
const logger$g = credentialLogger("AuthorizationCodeCredential");
|
|
41393
41529
|
/**
|
|
41394
41530
|
* Enables authentication to Azure Active Directory using an authorization code
|
|
41395
41531
|
* that was obtained through the authorization code flow, described in more detail
|
|
@@ -41404,6 +41540,7 @@ class AuthorizationCodeCredential {
|
|
|
41404
41540
|
*/
|
|
41405
41541
|
constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
|
|
41406
41542
|
this.lastTokenResponse = null;
|
|
41543
|
+
checkTenantId(logger$g, tenantId);
|
|
41407
41544
|
this.clientId = clientId;
|
|
41408
41545
|
this.tenantId = tenantId;
|
|
41409
41546
|
if (typeof redirectUriOrOptions === "string") {
|
|
@@ -41470,7 +41607,7 @@ class AuthorizationCodeCredential {
|
|
|
41470
41607
|
tokenResponse = yield this.identityClient.sendTokenRequest(webResource);
|
|
41471
41608
|
}
|
|
41472
41609
|
this.lastTokenResponse = tokenResponse;
|
|
41473
|
-
logger$
|
|
41610
|
+
logger$g.getToken.info(formatSuccess(scopes));
|
|
41474
41611
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
41475
41612
|
}
|
|
41476
41613
|
catch (err) {
|
|
@@ -41481,7 +41618,7 @@ class AuthorizationCodeCredential {
|
|
|
41481
41618
|
code,
|
|
41482
41619
|
message: err.message
|
|
41483
41620
|
});
|
|
41484
|
-
logger$
|
|
41621
|
+
logger$g.getToken.info(formatError(scopes, err));
|
|
41485
41622
|
throw err;
|
|
41486
41623
|
}
|
|
41487
41624
|
finally {
|