@azure/identity 3.2.0-alpha.20230213.2 → 3.2.0-alpha.20230227.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/README.md +2 -0
- package/dist/index.js +262 -232
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +9 -0
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js +7 -0
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +35 -29
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +10 -65
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
- package/dist-esm/src/credentials/workloadIdentityCredential.browser.js +27 -0
- package/dist-esm/src/credentials/workloadIdentityCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/workloadIdentityCredential.js +55 -0
- package/dist-esm/src/credentials/workloadIdentityCredential.js.map +1 -0
- package/dist-esm/src/credentials/workloadIdentityCredentialOptions.js +4 -0
- package/dist-esm/src/credentials/workloadIdentityCredentialOptions.js.map +1 -0
- package/dist-esm/src/index.js +1 -0
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/util/processMultiTenantRequest.js +1 -0
- package/dist-esm/src/util/processMultiTenantRequest.js.map +1 -1
- package/package.json +3 -1
- package/types/identity.d.ts +49 -0
package/dist/index.js
CHANGED
|
@@ -14,10 +14,11 @@ var coreTracing = require('@azure/core-tracing');
|
|
|
14
14
|
var fs = require('fs');
|
|
15
15
|
var os = require('os');
|
|
16
16
|
var path = require('path');
|
|
17
|
-
var
|
|
17
|
+
var promises = require('fs/promises');
|
|
18
18
|
var https = require('https');
|
|
19
19
|
var child_process = require('child_process');
|
|
20
20
|
var crypto = require('crypto');
|
|
21
|
+
var util = require('util');
|
|
21
22
|
var http = require('http');
|
|
22
23
|
var open = require('open');
|
|
23
24
|
var stoppable = require('stoppable');
|
|
@@ -553,6 +554,7 @@ function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowe
|
|
|
553
554
|
else {
|
|
554
555
|
resolvedTenantId = (_a = getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.tenantId) !== null && _a !== void 0 ? _a : tenantId;
|
|
555
556
|
}
|
|
557
|
+
console.log(resolvedTenantId);
|
|
556
558
|
if (tenantId &&
|
|
557
559
|
resolvedTenantId !== tenantId &&
|
|
558
560
|
!additionallyAllowedTenantIds.includes("*") &&
|
|
@@ -724,6 +726,8 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
724
726
|
this.authorityHost = baseUri;
|
|
725
727
|
this.abortControllers = new Map();
|
|
726
728
|
this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
|
|
729
|
+
// used for WorkloadIdentity
|
|
730
|
+
this.tokenCredentialOptions = Object.assign({}, options);
|
|
727
731
|
}
|
|
728
732
|
async sendTokenRequest(request) {
|
|
729
733
|
logger$m.info(`IdentityClient: sending token request to [${request.url}]`);
|
|
@@ -869,6 +873,13 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
|
869
873
|
status: response.status,
|
|
870
874
|
};
|
|
871
875
|
}
|
|
876
|
+
/**
|
|
877
|
+
*
|
|
878
|
+
* @internal
|
|
879
|
+
*/
|
|
880
|
+
getTokenCredentialOptions() {
|
|
881
|
+
return this.tokenCredentialOptions;
|
|
882
|
+
}
|
|
872
883
|
/**
|
|
873
884
|
* If allowLoggingAccountIdentifiers was set on the constructor options
|
|
874
885
|
* we try to log the account identifiers by parsing the received access token.
|
|
@@ -1479,7 +1490,7 @@ const logger$k = credentialLogger(msiName$6);
|
|
|
1479
1490
|
/**
|
|
1480
1491
|
* Generates the options used on the request for an access token.
|
|
1481
1492
|
*/
|
|
1482
|
-
function prepareRequestOptions$
|
|
1493
|
+
function prepareRequestOptions$5(scopes, clientId) {
|
|
1483
1494
|
const resource = mapScopesToResource(scopes);
|
|
1484
1495
|
if (!resource) {
|
|
1485
1496
|
throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
|
|
@@ -1512,6 +1523,7 @@ function prepareRequestOptions$6(scopes, clientId) {
|
|
|
1512
1523
|
* 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.
|
|
1513
1524
|
*/
|
|
1514
1525
|
const appServiceMsi2017 = {
|
|
1526
|
+
name: "appServiceMsi2017",
|
|
1515
1527
|
async isAvailable({ scopes }) {
|
|
1516
1528
|
const resource = mapScopesToResource(scopes);
|
|
1517
1529
|
if (!resource) {
|
|
@@ -1531,7 +1543,7 @@ const appServiceMsi2017 = {
|
|
|
1531
1543
|
logger$k.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
1532
1544
|
}
|
|
1533
1545
|
logger$k.info(`${msiName$6}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
1534
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1546
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
|
|
1535
1547
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1536
1548
|
allowInsecureConnection: true }));
|
|
1537
1549
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -1545,7 +1557,7 @@ const logger$j = credentialLogger(msiName$5);
|
|
|
1545
1557
|
/**
|
|
1546
1558
|
* Generates the options used on the request for an access token.
|
|
1547
1559
|
*/
|
|
1548
|
-
function prepareRequestOptions$
|
|
1560
|
+
function prepareRequestOptions$4(scopes, clientId, resourceId) {
|
|
1549
1561
|
const resource = mapScopesToResource(scopes);
|
|
1550
1562
|
if (!resource) {
|
|
1551
1563
|
throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
|
|
@@ -1580,6 +1592,7 @@ function prepareRequestOptions$5(scopes, clientId, resourceId) {
|
|
|
1580
1592
|
* 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.
|
|
1581
1593
|
*/
|
|
1582
1594
|
const cloudShellMsi = {
|
|
1595
|
+
name: "cloudShellMsi",
|
|
1583
1596
|
async isAvailable({ scopes }) {
|
|
1584
1597
|
const resource = mapScopesToResource(scopes);
|
|
1585
1598
|
if (!resource) {
|
|
@@ -1601,7 +1614,7 @@ const cloudShellMsi = {
|
|
|
1601
1614
|
logger$j.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
|
|
1602
1615
|
}
|
|
1603
1616
|
logger$j.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
1604
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1617
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
|
|
1605
1618
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1606
1619
|
allowInsecureConnection: true }));
|
|
1607
1620
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
@@ -1615,7 +1628,7 @@ const logger$i = credentialLogger(msiName$4);
|
|
|
1615
1628
|
/**
|
|
1616
1629
|
* Generates the options used on the request for an access token.
|
|
1617
1630
|
*/
|
|
1618
|
-
function prepareRequestOptions$
|
|
1631
|
+
function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
|
|
1619
1632
|
var _a;
|
|
1620
1633
|
const resource = mapScopesToResource(scopes);
|
|
1621
1634
|
if (!resource) {
|
|
@@ -1665,6 +1678,7 @@ const imdsMsiRetryConfig = {
|
|
|
1665
1678
|
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
1666
1679
|
*/
|
|
1667
1680
|
const imdsMsi = {
|
|
1681
|
+
name: "imdsMsi",
|
|
1668
1682
|
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
|
|
1669
1683
|
const resource = mapScopesToResource(scopes);
|
|
1670
1684
|
if (!resource) {
|
|
@@ -1678,7 +1692,7 @@ const imdsMsi = {
|
|
|
1678
1692
|
if (!identityClient) {
|
|
1679
1693
|
throw new Error("Missing IdentityClient");
|
|
1680
1694
|
}
|
|
1681
|
-
const requestOptions = prepareRequestOptions$
|
|
1695
|
+
const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
|
|
1682
1696
|
skipMetadataHeader: true,
|
|
1683
1697
|
skipQuery: true,
|
|
1684
1698
|
});
|
|
@@ -1723,7 +1737,7 @@ const imdsMsi = {
|
|
|
1723
1737
|
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
|
|
1724
1738
|
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
|
|
1725
1739
|
try {
|
|
1726
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1740
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
|
|
1727
1741
|
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1728
1742
|
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
1729
1743
|
}
|
|
@@ -1746,7 +1760,7 @@ const logger$h = credentialLogger(msiName$3);
|
|
|
1746
1760
|
/**
|
|
1747
1761
|
* Generates the options used on the request for an access token.
|
|
1748
1762
|
*/
|
|
1749
|
-
function prepareRequestOptions$
|
|
1763
|
+
function prepareRequestOptions$2(scopes, clientId, resourceId) {
|
|
1750
1764
|
const resource = mapScopesToResource(scopes);
|
|
1751
1765
|
if (!resource) {
|
|
1752
1766
|
throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
|
|
@@ -1780,7 +1794,7 @@ function prepareRequestOptions$3(scopes, clientId, resourceId) {
|
|
|
1780
1794
|
* Retrieves the file contents at the given path using promises.
|
|
1781
1795
|
* Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
|
|
1782
1796
|
*/
|
|
1783
|
-
function readFileAsync$
|
|
1797
|
+
function readFileAsync$1(path, options) {
|
|
1784
1798
|
return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
|
|
1785
1799
|
if (err) {
|
|
1786
1800
|
reject(err);
|
|
@@ -1812,6 +1826,7 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
1812
1826
|
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
|
|
1813
1827
|
*/
|
|
1814
1828
|
const arcMsi = {
|
|
1829
|
+
name: "arc",
|
|
1815
1830
|
async isAvailable({ scopes }) {
|
|
1816
1831
|
const resource = mapScopesToResource(scopes);
|
|
1817
1832
|
if (!resource) {
|
|
@@ -1834,12 +1849,12 @@ const arcMsi = {
|
|
|
1834
1849
|
logger$h.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
|
|
1835
1850
|
}
|
|
1836
1851
|
logger$h.info(`${msiName$3}: Authenticating.`);
|
|
1837
|
-
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$
|
|
1852
|
+
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
|
1838
1853
|
const filePath = await filePathRequest(identityClient, requestOptions);
|
|
1839
1854
|
if (!filePath) {
|
|
1840
1855
|
throw new Error(`${msiName$3}: Failed to find the token file.`);
|
|
1841
1856
|
}
|
|
1842
|
-
const key = await readFileAsync$
|
|
1857
|
+
const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
|
|
1843
1858
|
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
|
1844
1859
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
|
|
1845
1860
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
@@ -1850,82 +1865,164 @@ const arcMsi = {
|
|
|
1850
1865
|
};
|
|
1851
1866
|
|
|
1852
1867
|
// Copyright (c) Microsoft Corporation.
|
|
1853
|
-
const msiName$2 = "ManagedIdentityCredential - Token Exchange";
|
|
1854
|
-
const logger$g = credentialLogger(msiName$2);
|
|
1855
|
-
const readFileAsync$1 = util.promisify(fs__default["default"].readFile);
|
|
1856
1868
|
/**
|
|
1857
|
-
*
|
|
1869
|
+
* MSAL client assertion client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
|
|
1870
|
+
* @internal
|
|
1858
1871
|
*/
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1872
|
+
class MsalClientAssertion extends MsalNode {
|
|
1873
|
+
constructor(options) {
|
|
1874
|
+
super(options);
|
|
1875
|
+
this.requiresConfidential = true;
|
|
1876
|
+
this.getAssertion = options.getAssertion;
|
|
1877
|
+
}
|
|
1878
|
+
async doGetToken(scopes, options = {}) {
|
|
1879
|
+
try {
|
|
1880
|
+
const assertion = await this.getAssertion();
|
|
1881
|
+
const result = await this.confidentialApp.acquireTokenByClientCredential({
|
|
1882
|
+
scopes,
|
|
1883
|
+
correlationId: options.correlationId,
|
|
1884
|
+
azureRegion: this.azureRegion,
|
|
1885
|
+
authority: options.authority,
|
|
1886
|
+
claims: options.claims,
|
|
1887
|
+
clientAssertion: assertion,
|
|
1888
|
+
});
|
|
1889
|
+
// The Client Credential flow does not return an account,
|
|
1890
|
+
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
1891
|
+
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
1892
|
+
}
|
|
1893
|
+
catch (err) {
|
|
1894
|
+
let err2 = err;
|
|
1895
|
+
if (err === null || err === undefined) {
|
|
1896
|
+
err2 = new Error(JSON.stringify(err));
|
|
1897
|
+
}
|
|
1898
|
+
else {
|
|
1899
|
+
err2 = coreUtil.isError(err) ? err : new Error(String(err));
|
|
1900
|
+
}
|
|
1901
|
+
throw this.handleError(scopes, err2, options);
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1878
1904
|
}
|
|
1905
|
+
|
|
1906
|
+
// Copyright (c) Microsoft Corporation.
|
|
1907
|
+
const logger$g = credentialLogger("ClientAssertionCredential");
|
|
1879
1908
|
/**
|
|
1880
|
-
*
|
|
1909
|
+
* Authenticates a service principal with a JWT assertion.
|
|
1881
1910
|
*/
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1911
|
+
class ClientAssertionCredential {
|
|
1912
|
+
/**
|
|
1913
|
+
* Creates an instance of the ClientAssertionCredential with the details
|
|
1914
|
+
* needed to authenticate against Azure Active Directory with a client
|
|
1915
|
+
* assertion provided by the developer through the `getAssertion` function parameter.
|
|
1916
|
+
*
|
|
1917
|
+
* @param tenantId - The Azure Active Directory tenant (directory) ID.
|
|
1918
|
+
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
1919
|
+
* @param getAssertion - A function that retrieves the assertion for the credential to use.
|
|
1920
|
+
* @param options - Options for configuring the client which makes the authentication request.
|
|
1921
|
+
*/
|
|
1922
|
+
constructor(tenantId, clientId, getAssertion, options = {}) {
|
|
1923
|
+
if (!tenantId || !clientId || !getAssertion) {
|
|
1924
|
+
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
|
|
1925
|
+
}
|
|
1926
|
+
this.tenantId = tenantId;
|
|
1927
|
+
this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
1928
|
+
this.clientId = clientId;
|
|
1929
|
+
this.options = options;
|
|
1930
|
+
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$g, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
|
|
1931
|
+
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Authenticates with Azure Active Directory and returns an access token if successful.
|
|
1934
|
+
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
1935
|
+
*
|
|
1936
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
1937
|
+
* @param options - The options used to configure any requests this
|
|
1938
|
+
* TokenCredential implementation might make.
|
|
1939
|
+
*/
|
|
1940
|
+
async getToken(scopes, options = {}) {
|
|
1941
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
1942
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
1943
|
+
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
1944
|
+
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
// Copyright (c) Microsoft Corporation.
|
|
1950
|
+
/**
|
|
1951
|
+
* WorkloadIdentityCredential supports Azure workload identity authentication on Kubernetes.
|
|
1952
|
+
* Refer to <a href="https://learn.microsoft.com/azure/aks/workload-identity-overview">Azure Active Directory Workload Identity</a>
|
|
1953
|
+
* for more information.
|
|
1954
|
+
*/
|
|
1955
|
+
class WorkloadIdentityCredential {
|
|
1956
|
+
/**
|
|
1957
|
+
* WorkloadIdentityCredential supports Azure workload identity on Kubernetes.
|
|
1958
|
+
*
|
|
1959
|
+
* @param options - The identity client options to use for authentication.
|
|
1960
|
+
*/
|
|
1961
|
+
constructor(options = {}) {
|
|
1962
|
+
this.azureFederatedTokenFileContent = undefined;
|
|
1963
|
+
this.cacheDate = undefined;
|
|
1964
|
+
if (!options.tenantId || !options.clientId || !options.federatedTokenFilePath) {
|
|
1965
|
+
throw new Error("WorkloadIdentityCredential: tenantId, clientId, and federatedTokenFilePath are required parameters.");
|
|
1966
|
+
}
|
|
1967
|
+
this.federatedTokenFilePath = options.federatedTokenFilePath;
|
|
1968
|
+
this.client = new ClientAssertionCredential(options.tenantId, options.clientId, this.readFileContents.bind(this), options);
|
|
1969
|
+
}
|
|
1970
|
+
/**
|
|
1971
|
+
* Authenticates with Azure Active Directory and returns an access token if successful.
|
|
1972
|
+
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
1973
|
+
*
|
|
1974
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
1975
|
+
* @param options - The options used to configure any requests this
|
|
1976
|
+
* TokenCredential implementation might make.
|
|
1977
|
+
*/
|
|
1978
|
+
getToken(scopes, options) {
|
|
1979
|
+
return this.client.getToken(scopes, options);
|
|
1980
|
+
}
|
|
1981
|
+
async readFileContents() {
|
|
1888
1982
|
// Cached assertions expire after 5 minutes
|
|
1889
|
-
if (cacheDate !== undefined && Date.now() - cacheDate >= 1000 * 60 * 5) {
|
|
1890
|
-
azureFederatedTokenFileContent = undefined;
|
|
1983
|
+
if (this.cacheDate !== undefined && Date.now() - this.cacheDate >= 1000 * 60 * 5) {
|
|
1984
|
+
this.azureFederatedTokenFileContent = undefined;
|
|
1891
1985
|
}
|
|
1892
|
-
if (!azureFederatedTokenFileContent) {
|
|
1893
|
-
const file = await
|
|
1986
|
+
if (!this.azureFederatedTokenFileContent) {
|
|
1987
|
+
const file = await promises.readFile(this.federatedTokenFilePath, "utf8");
|
|
1894
1988
|
const value = file.trim();
|
|
1895
1989
|
if (!value) {
|
|
1896
|
-
throw new Error(`No content on the file ${
|
|
1990
|
+
throw new Error(`No content on the file ${this.federatedTokenFilePath}.`);
|
|
1897
1991
|
}
|
|
1898
1992
|
else {
|
|
1899
|
-
azureFederatedTokenFileContent = value;
|
|
1900
|
-
cacheDate = Date.now();
|
|
1993
|
+
this.azureFederatedTokenFileContent = value;
|
|
1994
|
+
this.cacheDate = Date.now();
|
|
1901
1995
|
}
|
|
1902
1996
|
}
|
|
1903
|
-
return azureFederatedTokenFileContent;
|
|
1997
|
+
return this.azureFederatedTokenFileContent;
|
|
1904
1998
|
}
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
// Copyright (c) Microsoft Corporation.
|
|
2002
|
+
const msiName$2 = "ManagedIdentityCredential - Token Exchange";
|
|
2003
|
+
const logger$f = credentialLogger(msiName$2);
|
|
2004
|
+
/**
|
|
2005
|
+
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
|
|
2006
|
+
*/
|
|
2007
|
+
function tokenExchangeMsi() {
|
|
1905
2008
|
return {
|
|
2009
|
+
name: "tokenExchangeMsi",
|
|
1906
2010
|
async isAvailable({ clientId }) {
|
|
1907
2011
|
const env = process.env;
|
|
1908
|
-
const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
|
|
2012
|
+
const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
|
|
2013
|
+
env.AZURE_TENANT_ID &&
|
|
2014
|
+
process.env.AZURE_FEDERATED_TOKEN_FILE);
|
|
1909
2015
|
if (!result) {
|
|
1910
|
-
logger$
|
|
2016
|
+
logger$f.info(`${msiName$2}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
|
|
1911
2017
|
}
|
|
1912
2018
|
return result;
|
|
1913
2019
|
},
|
|
1914
2020
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1915
|
-
const {
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
}
|
|
1921
|
-
catch (err) {
|
|
1922
|
-
throw new Error(`${msiName$2}: Failed to read ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
|
|
1923
|
-
}
|
|
1924
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID)), {
|
|
1925
|
-
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
1926
|
-
allowInsecureConnection: true }));
|
|
1927
|
-
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
1928
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2021
|
+
const { scopes, clientId } = configuration;
|
|
2022
|
+
const identityClientTokenCredentialOptions = {};
|
|
2023
|
+
const workloadIdentityCredential = new WorkloadIdentityCredential(Object.assign(Object.assign({ clientId, tenantId: process.env.AZURE_TENANT_ID, federatedTokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE }, identityClientTokenCredentialOptions), { disableInstanceDiscovery: true }));
|
|
2024
|
+
const token = await workloadIdentityCredential.getToken(scopes, getTokenOptions);
|
|
2025
|
+
return token;
|
|
1929
2026
|
},
|
|
1930
2027
|
};
|
|
1931
2028
|
}
|
|
@@ -1942,7 +2039,7 @@ function tokenExchangeMsi() {
|
|
|
1942
2039
|
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
1943
2040
|
//
|
|
1944
2041
|
const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
|
|
1945
|
-
const logger$
|
|
2042
|
+
const logger$e = credentialLogger(msiName$1);
|
|
1946
2043
|
/**
|
|
1947
2044
|
* Generates the options used on the request for an access token.
|
|
1948
2045
|
*/
|
|
@@ -1982,25 +2079,26 @@ function prepareRequestOptions$1(scopes, clientId, resourceId) {
|
|
|
1982
2079
|
* 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.
|
|
1983
2080
|
*/
|
|
1984
2081
|
const fabricMsi = {
|
|
2082
|
+
name: "fabricMsi",
|
|
1985
2083
|
async isAvailable({ scopes }) {
|
|
1986
2084
|
const resource = mapScopesToResource(scopes);
|
|
1987
2085
|
if (!resource) {
|
|
1988
|
-
logger$
|
|
2086
|
+
logger$e.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
|
|
1989
2087
|
return false;
|
|
1990
2088
|
}
|
|
1991
2089
|
const env = process.env;
|
|
1992
2090
|
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
|
|
1993
2091
|
if (!result) {
|
|
1994
|
-
logger$
|
|
2092
|
+
logger$e.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
|
|
1995
2093
|
}
|
|
1996
2094
|
return result;
|
|
1997
2095
|
},
|
|
1998
2096
|
async getToken(configuration, getTokenOptions = {}) {
|
|
1999
2097
|
const { scopes, identityClient, clientId, resourceId } = configuration;
|
|
2000
2098
|
if (resourceId) {
|
|
2001
|
-
logger$
|
|
2099
|
+
logger$e.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
|
|
2002
2100
|
}
|
|
2003
|
-
logger$
|
|
2101
|
+
logger$e.info([
|
|
2004
2102
|
`${msiName$1}:`,
|
|
2005
2103
|
"Using the endpoint and the secret coming from the environment variables:",
|
|
2006
2104
|
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
|
|
@@ -2020,7 +2118,7 @@ const fabricMsi = {
|
|
|
2020
2118
|
|
|
2021
2119
|
// Copyright (c) Microsoft Corporation.
|
|
2022
2120
|
const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
|
|
2023
|
-
const logger$
|
|
2121
|
+
const logger$d = credentialLogger(msiName);
|
|
2024
2122
|
/**
|
|
2025
2123
|
* Generates the options used on the request for an access token.
|
|
2026
2124
|
*/
|
|
@@ -2060,22 +2158,23 @@ function prepareRequestOptions(scopes, clientId, resourceId) {
|
|
|
2060
2158
|
* 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.
|
|
2061
2159
|
*/
|
|
2062
2160
|
const appServiceMsi2019 = {
|
|
2161
|
+
name: "appServiceMsi2019",
|
|
2063
2162
|
async isAvailable({ scopes }) {
|
|
2064
2163
|
const resource = mapScopesToResource(scopes);
|
|
2065
2164
|
if (!resource) {
|
|
2066
|
-
logger$
|
|
2165
|
+
logger$d.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
|
|
2067
2166
|
return false;
|
|
2068
2167
|
}
|
|
2069
2168
|
const env = process.env;
|
|
2070
2169
|
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
|
|
2071
2170
|
if (!result) {
|
|
2072
|
-
logger$
|
|
2171
|
+
logger$d.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
|
|
2073
2172
|
}
|
|
2074
2173
|
return result;
|
|
2075
2174
|
},
|
|
2076
2175
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2077
2176
|
const { identityClient, scopes, clientId, resourceId } = configuration;
|
|
2078
|
-
logger$
|
|
2177
|
+
logger$d.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
|
|
2079
2178
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
|
|
2080
2179
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2081
2180
|
allowInsecureConnection: true }));
|
|
@@ -2085,7 +2184,7 @@ const appServiceMsi2019 = {
|
|
|
2085
2184
|
};
|
|
2086
2185
|
|
|
2087
2186
|
// Copyright (c) Microsoft Corporation.
|
|
2088
|
-
const logger$
|
|
2187
|
+
const logger$c = credentialLogger("ManagedIdentityCredential");
|
|
2089
2188
|
/**
|
|
2090
2189
|
* Attempts authentication using a managed identity available at the deployment environment.
|
|
2091
2190
|
* This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
|
|
@@ -2199,35 +2298,41 @@ class ManagedIdentityCredential {
|
|
|
2199
2298
|
// If it's null, it means we don't yet know whether
|
|
2200
2299
|
// the endpoint is available and need to check for it.
|
|
2201
2300
|
if (this.isEndpointUnavailable !== true) {
|
|
2202
|
-
const
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
expiresInSeconds
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2301
|
+
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
|
|
2302
|
+
if (availableMSI.name === "tokenExchangeMsi") {
|
|
2303
|
+
result = await this.authenticateManagedIdentity(scopes, updatedOptions);
|
|
2304
|
+
}
|
|
2305
|
+
else {
|
|
2306
|
+
const appTokenParameters = {
|
|
2307
|
+
correlationId: this.identityClient.getCorrelationId(),
|
|
2308
|
+
tenantId: (options === null || options === void 0 ? void 0 : options.tenantId) || "organizations",
|
|
2309
|
+
scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
2310
|
+
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
2311
|
+
};
|
|
2312
|
+
this.confidentialApp.SetAppTokenProvider(async (appTokenProviderParameters = appTokenParameters) => {
|
|
2313
|
+
logger$c.info(`SetAppTokenProvider invoked with parameters- ${JSON.stringify(appTokenProviderParameters)}`);
|
|
2314
|
+
const resultToken = await this.authenticateManagedIdentity(scopes, Object.assign(Object.assign({}, updatedOptions), appTokenProviderParameters));
|
|
2315
|
+
if (resultToken) {
|
|
2316
|
+
logger$c.info(`SetAppTokenProvider has saved the token in cache`);
|
|
2317
|
+
const expiresInSeconds = (resultToken === null || resultToken === void 0 ? void 0 : resultToken.expiresOnTimestamp)
|
|
2318
|
+
? Math.floor((resultToken.expiresOnTimestamp - Date.now()) / 1000)
|
|
2319
|
+
: 0;
|
|
2320
|
+
return {
|
|
2321
|
+
accessToken: resultToken === null || resultToken === void 0 ? void 0 : resultToken.token,
|
|
2322
|
+
expiresInSeconds,
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
logger$c.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
|
|
2327
|
+
return {
|
|
2328
|
+
accessToken: "no_access_token_returned",
|
|
2329
|
+
expiresInSeconds: 0,
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
});
|
|
2333
|
+
const authenticationResult = await this.confidentialApp.acquireTokenByClientCredential(Object.assign({}, appTokenParameters));
|
|
2334
|
+
result = this.handleResult(scopes, authenticationResult || undefined);
|
|
2335
|
+
}
|
|
2231
2336
|
if (result === null) {
|
|
2232
2337
|
// If authenticateManagedIdentity returns null,
|
|
2233
2338
|
// it means no MSI endpoints are available.
|
|
@@ -2236,7 +2341,7 @@ class ManagedIdentityCredential {
|
|
|
2236
2341
|
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
|
|
2237
2342
|
// yet we had no access token. For this reason, we'll throw once with a specific message:
|
|
2238
2343
|
const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
|
|
2239
|
-
logger$
|
|
2344
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2240
2345
|
throw error;
|
|
2241
2346
|
}
|
|
2242
2347
|
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
|
|
@@ -2248,10 +2353,10 @@ class ManagedIdentityCredential {
|
|
|
2248
2353
|
// We've previously determined that the endpoint was unavailable,
|
|
2249
2354
|
// either because it was unreachable or permanently unable to authenticate.
|
|
2250
2355
|
const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
|
|
2251
|
-
logger$
|
|
2356
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2252
2357
|
throw error;
|
|
2253
2358
|
}
|
|
2254
|
-
logger$
|
|
2359
|
+
logger$c.getToken.info(formatSuccess(scopes));
|
|
2255
2360
|
return result;
|
|
2256
2361
|
}
|
|
2257
2362
|
catch (err) {
|
|
@@ -2273,14 +2378,14 @@ class ManagedIdentityCredential {
|
|
|
2273
2378
|
// we can safely assume the credential is unavailable.
|
|
2274
2379
|
if (err.code === "ENETUNREACH") {
|
|
2275
2380
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
|
|
2276
|
-
logger$
|
|
2381
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2277
2382
|
throw error;
|
|
2278
2383
|
}
|
|
2279
2384
|
// If either the host was unreachable,
|
|
2280
2385
|
// we can safely assume the credential is unavailable.
|
|
2281
2386
|
if (err.code === "EHOSTUNREACH") {
|
|
2282
2387
|
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
|
|
2283
|
-
logger$
|
|
2388
|
+
logger$c.getToken.info(formatError(scopes, error));
|
|
2284
2389
|
throw error;
|
|
2285
2390
|
}
|
|
2286
2391
|
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
|
@@ -2311,7 +2416,7 @@ class ManagedIdentityCredential {
|
|
|
2311
2416
|
*/
|
|
2312
2417
|
handleResult(scopes, result, getTokenOptions) {
|
|
2313
2418
|
this.ensureValidMsalToken(scopes, result, getTokenOptions);
|
|
2314
|
-
logger$
|
|
2419
|
+
logger$c.getToken.info(formatSuccess(scopes));
|
|
2315
2420
|
return {
|
|
2316
2421
|
token: result.accessToken,
|
|
2317
2422
|
expiresOnTimestamp: result.expiresOn.getTime(),
|
|
@@ -2323,7 +2428,7 @@ class ManagedIdentityCredential {
|
|
|
2323
2428
|
*/
|
|
2324
2429
|
ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
|
|
2325
2430
|
const error = (message) => {
|
|
2326
|
-
logger$
|
|
2431
|
+
logger$c.getToken.info(message);
|
|
2327
2432
|
return new AuthenticationRequiredError({
|
|
2328
2433
|
scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
2329
2434
|
getTokenOptions,
|
|
@@ -2419,7 +2524,7 @@ const cliCredentialInternals = {
|
|
|
2419
2524
|
});
|
|
2420
2525
|
},
|
|
2421
2526
|
};
|
|
2422
|
-
const logger$
|
|
2527
|
+
const logger$b = credentialLogger("AzureCliCredential");
|
|
2423
2528
|
/**
|
|
2424
2529
|
* This credential will use the currently logged-in user login information
|
|
2425
2530
|
* via the Azure CLI ('az') commandline tool.
|
|
@@ -2450,8 +2555,8 @@ class AzureCliCredential {
|
|
|
2450
2555
|
async getToken(scopes, options = {}) {
|
|
2451
2556
|
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
|
|
2452
2557
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
2453
|
-
logger$
|
|
2454
|
-
ensureValidScope(scope, logger$
|
|
2558
|
+
logger$b.getToken.info(`Using the scope ${scope}`);
|
|
2559
|
+
ensureValidScope(scope, logger$b);
|
|
2455
2560
|
const resource = getScopeResource(scope);
|
|
2456
2561
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
2457
2562
|
var _a, _b, _c, _d;
|
|
@@ -2462,18 +2567,18 @@ class AzureCliCredential {
|
|
|
2462
2567
|
const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
|
|
2463
2568
|
if (isNotInstallError) {
|
|
2464
2569
|
const error = new CredentialUnavailableError("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");
|
|
2465
|
-
logger$
|
|
2570
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
2466
2571
|
throw error;
|
|
2467
2572
|
}
|
|
2468
2573
|
if (isLoginError) {
|
|
2469
2574
|
const error = new CredentialUnavailableError("Please run 'az login' from a command prompt to authenticate before using this credential.");
|
|
2470
|
-
logger$
|
|
2575
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
2471
2576
|
throw error;
|
|
2472
2577
|
}
|
|
2473
2578
|
try {
|
|
2474
2579
|
const responseData = obj.stdout;
|
|
2475
2580
|
const response = JSON.parse(responseData);
|
|
2476
|
-
logger$
|
|
2581
|
+
logger$b.getToken.info(formatSuccess(scopes));
|
|
2477
2582
|
const returnValue = {
|
|
2478
2583
|
token: response.accessToken,
|
|
2479
2584
|
expiresOnTimestamp: new Date(response.expiresOn).getTime(),
|
|
@@ -2491,7 +2596,7 @@ class AzureCliCredential {
|
|
|
2491
2596
|
const error = err.name === "CredentialUnavailableError"
|
|
2492
2597
|
? err
|
|
2493
2598
|
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
|
|
2494
|
-
logger$
|
|
2599
|
+
logger$b.getToken.info(formatError(scopes, error));
|
|
2495
2600
|
throw error;
|
|
2496
2601
|
}
|
|
2497
2602
|
});
|
|
@@ -2529,7 +2634,7 @@ const processUtils = {
|
|
|
2529
2634
|
};
|
|
2530
2635
|
|
|
2531
2636
|
// Copyright (c) Microsoft Corporation.
|
|
2532
|
-
const logger$
|
|
2637
|
+
const logger$a = credentialLogger("AzurePowerShellCredential");
|
|
2533
2638
|
const isWindows = process.platform === "win32";
|
|
2534
2639
|
/**
|
|
2535
2640
|
* Returns a platform-appropriate command name by appending ".exe" on Windows.
|
|
@@ -2661,12 +2766,12 @@ class AzurePowerShellCredential {
|
|
|
2661
2766
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
2662
2767
|
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds);
|
|
2663
2768
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
|
2664
|
-
ensureValidScope(scope, logger$
|
|
2665
|
-
logger$
|
|
2769
|
+
ensureValidScope(scope, logger$a);
|
|
2770
|
+
logger$a.getToken.info(`Using the scope ${scope}`);
|
|
2666
2771
|
const resource = getScopeResource(scope);
|
|
2667
2772
|
try {
|
|
2668
2773
|
const response = await this.getAzurePowerShellAccessToken(resource, tenantId);
|
|
2669
|
-
logger$
|
|
2774
|
+
logger$a.getToken.info(formatSuccess(scopes));
|
|
2670
2775
|
return {
|
|
2671
2776
|
token: response.Token,
|
|
2672
2777
|
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
|
|
@@ -2675,16 +2780,16 @@ class AzurePowerShellCredential {
|
|
|
2675
2780
|
catch (err) {
|
|
2676
2781
|
if (isNotInstalledError(err)) {
|
|
2677
2782
|
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
|
|
2678
|
-
logger$
|
|
2783
|
+
logger$a.getToken.info(formatError(scope, error));
|
|
2679
2784
|
throw error;
|
|
2680
2785
|
}
|
|
2681
2786
|
else if (isLoginError(err)) {
|
|
2682
2787
|
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
|
|
2683
|
-
logger$
|
|
2788
|
+
logger$a.getToken.info(formatError(scope, error));
|
|
2684
2789
|
throw error;
|
|
2685
2790
|
}
|
|
2686
2791
|
const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
|
|
2687
|
-
logger$
|
|
2792
|
+
logger$a.getToken.info(formatError(scope, error));
|
|
2688
2793
|
throw error;
|
|
2689
2794
|
}
|
|
2690
2795
|
});
|
|
@@ -2695,7 +2800,7 @@ class AzurePowerShellCredential {
|
|
|
2695
2800
|
/**
|
|
2696
2801
|
* @internal
|
|
2697
2802
|
*/
|
|
2698
|
-
const logger$
|
|
2803
|
+
const logger$9 = credentialLogger("ChainedTokenCredential");
|
|
2699
2804
|
/**
|
|
2700
2805
|
* Enables multiple `TokenCredential` implementations to be tried in order
|
|
2701
2806
|
* until one of the getToken methods returns an access token.
|
|
@@ -2746,17 +2851,17 @@ class ChainedTokenCredential {
|
|
|
2746
2851
|
errors.push(err);
|
|
2747
2852
|
}
|
|
2748
2853
|
else {
|
|
2749
|
-
logger$
|
|
2854
|
+
logger$9.getToken.info(formatError(scopes, err));
|
|
2750
2855
|
throw err;
|
|
2751
2856
|
}
|
|
2752
2857
|
}
|
|
2753
2858
|
}
|
|
2754
2859
|
if (!token && errors.length > 0) {
|
|
2755
2860
|
const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed.");
|
|
2756
|
-
logger$
|
|
2861
|
+
logger$9.getToken.info(formatError(scopes, err));
|
|
2757
2862
|
throw err;
|
|
2758
2863
|
}
|
|
2759
|
-
logger$
|
|
2864
|
+
logger$9.getToken.info(`Result for ${successfulCredentialName}: ${formatSuccess(scopes)}`);
|
|
2760
2865
|
if (token === null) {
|
|
2761
2866
|
throw new CredentialUnavailableError("Failed to retrieve a valid token");
|
|
2762
2867
|
}
|
|
@@ -2872,7 +2977,7 @@ class MsalClientCertificate extends MsalNode {
|
|
|
2872
2977
|
|
|
2873
2978
|
// Copyright (c) Microsoft Corporation.
|
|
2874
2979
|
const credentialName$2 = "ClientCertificateCredential";
|
|
2875
|
-
const logger$
|
|
2980
|
+
const logger$8 = credentialLogger(credentialName$2);
|
|
2876
2981
|
/**
|
|
2877
2982
|
* Enables authentication to Azure Active Directory using a PEM-encoded
|
|
2878
2983
|
* certificate that is assigned to an App Registration. More information
|
|
@@ -2903,7 +3008,7 @@ class ClientCertificateCredential {
|
|
|
2903
3008
|
throw new Error(`${credentialName$2}: To avoid unexpected behaviors, providing both the contents of a PEM certificate and the path to a PEM certificate is forbidden. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
|
|
2904
3009
|
}
|
|
2905
3010
|
this.msalFlow = new MsalClientCertificate(Object.assign(Object.assign({}, options), { configuration,
|
|
2906
|
-
logger: logger$
|
|
3011
|
+
logger: logger$8,
|
|
2907
3012
|
clientId,
|
|
2908
3013
|
tenantId, sendCertificateChain: options.sendCertificateChain, tokenCredentialOptions: options }));
|
|
2909
3014
|
}
|
|
@@ -2955,7 +3060,7 @@ class MsalClientSecret extends MsalNode {
|
|
|
2955
3060
|
}
|
|
2956
3061
|
|
|
2957
3062
|
// Copyright (c) Microsoft Corporation.
|
|
2958
|
-
const logger$
|
|
3063
|
+
const logger$7 = credentialLogger("ClientSecretCredential");
|
|
2959
3064
|
/**
|
|
2960
3065
|
* Enables authentication to Azure Active Directory using a client secret
|
|
2961
3066
|
* that was generated for an App Registration. More information on how
|
|
@@ -2981,7 +3086,7 @@ class ClientSecretCredential {
|
|
|
2981
3086
|
}
|
|
2982
3087
|
this.tenantId = tenantId;
|
|
2983
3088
|
this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
2984
|
-
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$
|
|
3089
|
+
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger: logger$7,
|
|
2985
3090
|
clientId,
|
|
2986
3091
|
tenantId,
|
|
2987
3092
|
clientSecret, tokenCredentialOptions: options }));
|
|
@@ -3034,7 +3139,7 @@ class MsalUsernamePassword extends MsalNode {
|
|
|
3034
3139
|
}
|
|
3035
3140
|
|
|
3036
3141
|
// Copyright (c) Microsoft Corporation.
|
|
3037
|
-
const logger$
|
|
3142
|
+
const logger$6 = credentialLogger("UsernamePasswordCredential");
|
|
3038
3143
|
/**
|
|
3039
3144
|
* Enables authentication to Azure Active Directory with a user's
|
|
3040
3145
|
* username and password. This credential requires a high degree of
|
|
@@ -3059,7 +3164,7 @@ class UsernamePasswordCredential {
|
|
|
3059
3164
|
}
|
|
3060
3165
|
this.tenantId = tenantId;
|
|
3061
3166
|
this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3062
|
-
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$
|
|
3167
|
+
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$6,
|
|
3063
3168
|
clientId,
|
|
3064
3169
|
tenantId,
|
|
3065
3170
|
username,
|
|
@@ -3110,7 +3215,7 @@ function getAdditionallyAllowedTenants() {
|
|
|
3110
3215
|
return additionallyAllowedValues.split(";");
|
|
3111
3216
|
}
|
|
3112
3217
|
const credentialName$1 = "EnvironmentCredential";
|
|
3113
|
-
const logger$
|
|
3218
|
+
const logger$5 = credentialLogger(credentialName$1);
|
|
3114
3219
|
/**
|
|
3115
3220
|
* Enables authentication to Azure Active Directory using a client secret or certificate, or as a user
|
|
3116
3221
|
* with a username and password.
|
|
@@ -3144,29 +3249,29 @@ class EnvironmentCredential {
|
|
|
3144
3249
|
// Keep track of any missing environment variables for error details
|
|
3145
3250
|
this._credential = undefined;
|
|
3146
3251
|
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
|
|
3147
|
-
logger$
|
|
3252
|
+
logger$5.info(`Found the following environment variables: ${assigned}`);
|
|
3148
3253
|
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
3149
3254
|
const additionallyAllowedTenantIds = getAdditionallyAllowedTenants();
|
|
3150
3255
|
const newOptions = Object.assign(Object.assign({}, options), { additionallyAllowedTenantIds });
|
|
3151
3256
|
if (tenantId) {
|
|
3152
|
-
checkTenantId(logger$
|
|
3257
|
+
checkTenantId(logger$5, tenantId);
|
|
3153
3258
|
}
|
|
3154
3259
|
if (tenantId && clientId && clientSecret) {
|
|
3155
|
-
logger$
|
|
3260
|
+
logger$5.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
|
|
3156
3261
|
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, newOptions);
|
|
3157
3262
|
return;
|
|
3158
3263
|
}
|
|
3159
3264
|
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
|
|
3160
3265
|
const certificatePassword = process.env.AZURE_CLIENT_CERTIFICATE_PASSWORD;
|
|
3161
3266
|
if (tenantId && clientId && certificatePath) {
|
|
3162
|
-
logger$
|
|
3267
|
+
logger$5.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
|
|
3163
3268
|
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath, certificatePassword }, newOptions);
|
|
3164
3269
|
return;
|
|
3165
3270
|
}
|
|
3166
3271
|
const username = process.env.AZURE_USERNAME;
|
|
3167
3272
|
const password = process.env.AZURE_PASSWORD;
|
|
3168
3273
|
if (tenantId && clientId && username && password) {
|
|
3169
|
-
logger$
|
|
3274
|
+
logger$5.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
|
|
3170
3275
|
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, newOptions);
|
|
3171
3276
|
}
|
|
3172
3277
|
}
|
|
@@ -3181,7 +3286,7 @@ class EnvironmentCredential {
|
|
|
3181
3286
|
if (this._credential) {
|
|
3182
3287
|
try {
|
|
3183
3288
|
const result = await this._credential.getToken(scopes, newOptions);
|
|
3184
|
-
logger$
|
|
3289
|
+
logger$5.getToken.info(formatSuccess(scopes));
|
|
3185
3290
|
return result;
|
|
3186
3291
|
}
|
|
3187
3292
|
catch (err) {
|
|
@@ -3189,7 +3294,7 @@ class EnvironmentCredential {
|
|
|
3189
3294
|
error: `${credentialName$1} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
|
|
3190
3295
|
error_description: err.message.toString().split("More details:").join(""),
|
|
3191
3296
|
});
|
|
3192
|
-
logger$
|
|
3297
|
+
logger$5.getToken.info(formatError(scopes, authenticationError));
|
|
3193
3298
|
throw authenticationError;
|
|
3194
3299
|
}
|
|
3195
3300
|
}
|
|
@@ -3247,7 +3352,7 @@ const developerCliCredentialInternals = {
|
|
|
3247
3352
|
});
|
|
3248
3353
|
},
|
|
3249
3354
|
};
|
|
3250
|
-
const logger$
|
|
3355
|
+
const logger$4 = credentialLogger("AzureDeveloperCliCredential");
|
|
3251
3356
|
/**
|
|
3252
3357
|
* This credential will use the currently logged-in user login information
|
|
3253
3358
|
* via the Azure Developer CLI ('az') commandline tool.
|
|
@@ -3284,7 +3389,7 @@ class AzureDeveloperCliCredential {
|
|
|
3284
3389
|
else {
|
|
3285
3390
|
scopeList = scopes;
|
|
3286
3391
|
}
|
|
3287
|
-
logger$
|
|
3392
|
+
logger$4.getToken.info(`Using the scopes ${scopes}`);
|
|
3288
3393
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
|
3289
3394
|
var _a, _b, _c;
|
|
3290
3395
|
try {
|
|
@@ -3294,17 +3399,17 @@ class AzureDeveloperCliCredential {
|
|
|
3294
3399
|
((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.startsWith("'azd' is not recognized"));
|
|
3295
3400
|
if (isNotInstallError || (obj.error && obj.error.code === "ENOENT")) {
|
|
3296
3401
|
const error = new CredentialUnavailableError("Azure Developer CLI could not be found. Please visit https://aka.ms/azure-dev for installation instructions and then, once installed, authenticate to your Azure account using 'azd login'.");
|
|
3297
|
-
logger$
|
|
3402
|
+
logger$4.getToken.info(formatError(scopes, error));
|
|
3298
3403
|
throw error;
|
|
3299
3404
|
}
|
|
3300
3405
|
if (isNotLoggedInError) {
|
|
3301
3406
|
const error = new CredentialUnavailableError("Please run 'azd login' from a command prompt to authenticate before using this credential.");
|
|
3302
|
-
logger$
|
|
3407
|
+
logger$4.getToken.info(formatError(scopes, error));
|
|
3303
3408
|
throw error;
|
|
3304
3409
|
}
|
|
3305
3410
|
try {
|
|
3306
3411
|
const resp = JSON.parse(obj.stdout);
|
|
3307
|
-
logger$
|
|
3412
|
+
logger$4.getToken.info(formatSuccess(scopes));
|
|
3308
3413
|
return {
|
|
3309
3414
|
token: resp.token,
|
|
3310
3415
|
expiresOnTimestamp: new Date(resp.expiresOn).getTime(),
|
|
@@ -3321,7 +3426,7 @@ class AzureDeveloperCliCredential {
|
|
|
3321
3426
|
const error = err.name === "CredentialUnavailableError"
|
|
3322
3427
|
? err
|
|
3323
3428
|
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
|
|
3324
|
-
logger$
|
|
3429
|
+
logger$4.getToken.info(formatError(scopes, error));
|
|
3325
3430
|
throw error;
|
|
3326
3431
|
}
|
|
3327
3432
|
});
|
|
@@ -3342,11 +3447,16 @@ class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
|
|
|
3342
3447
|
var _a;
|
|
3343
3448
|
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
|
|
3344
3449
|
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
|
|
3450
|
+
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3345
3451
|
// ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
|
|
3346
3452
|
if (managedResourceId) {
|
|
3347
3453
|
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
|
|
3348
3454
|
super(managedIdentityResourceIdOptions);
|
|
3349
3455
|
}
|
|
3456
|
+
else if (workloadFile) {
|
|
3457
|
+
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId, federatedTokenFilePath: workloadFile });
|
|
3458
|
+
super(workloadIdentityCredentialOptions);
|
|
3459
|
+
}
|
|
3350
3460
|
else if (managedIdentityClientId) {
|
|
3351
3461
|
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
|
|
3352
3462
|
super(managedIdentityClientOptions);
|
|
@@ -3358,6 +3468,7 @@ class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
|
|
|
3358
3468
|
}
|
|
3359
3469
|
const defaultCredentials = [
|
|
3360
3470
|
EnvironmentCredential,
|
|
3471
|
+
WorkloadIdentityCredential,
|
|
3361
3472
|
DefaultManagedIdentityCredential,
|
|
3362
3473
|
AzureDeveloperCliCredential,
|
|
3363
3474
|
AzureCliCredential,
|
|
@@ -3373,88 +3484,6 @@ class DefaultAzureCredential extends ChainedTokenCredential {
|
|
|
3373
3484
|
}
|
|
3374
3485
|
}
|
|
3375
3486
|
|
|
3376
|
-
// Copyright (c) Microsoft Corporation.
|
|
3377
|
-
/**
|
|
3378
|
-
* MSAL client assertion client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
|
|
3379
|
-
* @internal
|
|
3380
|
-
*/
|
|
3381
|
-
class MsalClientAssertion extends MsalNode {
|
|
3382
|
-
constructor(options) {
|
|
3383
|
-
super(options);
|
|
3384
|
-
this.requiresConfidential = true;
|
|
3385
|
-
this.getAssertion = options.getAssertion;
|
|
3386
|
-
}
|
|
3387
|
-
async doGetToken(scopes, options = {}) {
|
|
3388
|
-
try {
|
|
3389
|
-
const assertion = await this.getAssertion();
|
|
3390
|
-
const result = await this.confidentialApp.acquireTokenByClientCredential({
|
|
3391
|
-
scopes,
|
|
3392
|
-
correlationId: options.correlationId,
|
|
3393
|
-
azureRegion: this.azureRegion,
|
|
3394
|
-
authority: options.authority,
|
|
3395
|
-
claims: options.claims,
|
|
3396
|
-
clientAssertion: assertion,
|
|
3397
|
-
});
|
|
3398
|
-
// The Client Credential flow does not return an account,
|
|
3399
|
-
// so each time getToken gets called, we will have to acquire a new token through the service.
|
|
3400
|
-
return this.handleResult(scopes, this.clientId, result || undefined);
|
|
3401
|
-
}
|
|
3402
|
-
catch (err) {
|
|
3403
|
-
let err2 = err;
|
|
3404
|
-
if (err === null || err === undefined) {
|
|
3405
|
-
err2 = new Error(JSON.stringify(err));
|
|
3406
|
-
}
|
|
3407
|
-
else {
|
|
3408
|
-
err2 = coreUtil.isError(err) ? err : new Error(String(err));
|
|
3409
|
-
}
|
|
3410
|
-
throw this.handleError(scopes, err2, options);
|
|
3411
|
-
}
|
|
3412
|
-
}
|
|
3413
|
-
}
|
|
3414
|
-
|
|
3415
|
-
// Copyright (c) Microsoft Corporation.
|
|
3416
|
-
const logger$4 = credentialLogger("ClientAssertionCredential");
|
|
3417
|
-
/**
|
|
3418
|
-
* Authenticates a service principal with a JWT assertion.
|
|
3419
|
-
*/
|
|
3420
|
-
class ClientAssertionCredential {
|
|
3421
|
-
/**
|
|
3422
|
-
* Creates an instance of the ClientAssertionCredential with the details
|
|
3423
|
-
* needed to authenticate against Azure Active Directory with a client
|
|
3424
|
-
* assertion provided by the developer through the `getAssertion` function parameter.
|
|
3425
|
-
*
|
|
3426
|
-
* @param tenantId - The Azure Active Directory tenant (directory) ID.
|
|
3427
|
-
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
3428
|
-
* @param getAssertion - A function that retrieves the assertion for the credential to use.
|
|
3429
|
-
* @param options - Options for configuring the client which makes the authentication request.
|
|
3430
|
-
*/
|
|
3431
|
-
constructor(tenantId, clientId, getAssertion, options = {}) {
|
|
3432
|
-
if (!tenantId || !clientId || !getAssertion) {
|
|
3433
|
-
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
|
|
3434
|
-
}
|
|
3435
|
-
this.tenantId = tenantId;
|
|
3436
|
-
this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3437
|
-
this.clientId = clientId;
|
|
3438
|
-
this.options = options;
|
|
3439
|
-
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$4, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
|
|
3440
|
-
}
|
|
3441
|
-
/**
|
|
3442
|
-
* Authenticates with Azure Active Directory and returns an access token if successful.
|
|
3443
|
-
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3444
|
-
*
|
|
3445
|
-
* @param scopes - The list of scopes for which the token will have access.
|
|
3446
|
-
* @param options - The options used to configure any requests this
|
|
3447
|
-
* TokenCredential implementation might make.
|
|
3448
|
-
*/
|
|
3449
|
-
async getToken(scopes, options = {}) {
|
|
3450
|
-
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3451
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
3452
|
-
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3453
|
-
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3454
|
-
});
|
|
3455
|
-
}
|
|
3456
|
-
}
|
|
3457
|
-
|
|
3458
3487
|
// Copyright (c) Microsoft Corporation.
|
|
3459
3488
|
/**
|
|
3460
3489
|
* A call to open(), but mockable
|
|
@@ -4009,6 +4038,7 @@ exports.ManagedIdentityCredential = ManagedIdentityCredential;
|
|
|
4009
4038
|
exports.OnBehalfOfCredential = OnBehalfOfCredential;
|
|
4010
4039
|
exports.UsernamePasswordCredential = UsernamePasswordCredential;
|
|
4011
4040
|
exports.VisualStudioCodeCredential = VisualStudioCodeCredential;
|
|
4041
|
+
exports.WorkloadIdentityCredential = WorkloadIdentityCredential;
|
|
4012
4042
|
exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord;
|
|
4013
4043
|
exports.getDefaultAzureCredential = getDefaultAzureCredential;
|
|
4014
4044
|
exports.logger = logger$m;
|