@azure/identity 4.3.0-beta.1 → 4.3.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.
- package/README.md +5 -9
- package/dist/index.js +597 -636
- package/dist/index.js.map +1 -1
- package/dist-esm/src/constants.js +1 -1
- package/dist-esm/src/constants.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +5 -7
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azurePipelinesCredential.js +35 -60
- package/dist-esm/src/credentials/azurePipelinesCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +41 -18
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.js +5 -7
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClient.js +63 -22
- package/dist-esm/src/msal/nodeFlows/msalClient.js.map +1 -1
- package/package.json +7 -7
- package/types/identity.d.ts +8 -10
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ var fs = require('fs');
|
|
|
12
12
|
var os = require('os');
|
|
13
13
|
var path = require('path');
|
|
14
14
|
var msalCommon = require('@azure/msal-node');
|
|
15
|
+
var fs$1 = require('node:fs');
|
|
15
16
|
var https = require('https');
|
|
16
17
|
var promises = require('fs/promises');
|
|
17
18
|
var child_process = require('child_process');
|
|
@@ -44,7 +45,7 @@ var child_process__namespace = /*#__PURE__*/_interopNamespaceDefault(child_proce
|
|
|
44
45
|
/**
|
|
45
46
|
* Current version of the `@azure/identity` package.
|
|
46
47
|
*/
|
|
47
|
-
const SDK_VERSION = `4.3.0-beta.
|
|
48
|
+
const SDK_VERSION = `4.3.0-beta.3`;
|
|
48
49
|
/**
|
|
49
50
|
* The default client ID for authentication
|
|
50
51
|
* @internal
|
|
@@ -1179,18 +1180,6 @@ function prepareRequestOptions$3(scopes, clientId, resourceId) {
|
|
|
1179
1180
|
}),
|
|
1180
1181
|
});
|
|
1181
1182
|
}
|
|
1182
|
-
/**
|
|
1183
|
-
* Retrieves the file contents at the given path using promises.
|
|
1184
|
-
* Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
|
|
1185
|
-
*/
|
|
1186
|
-
function readFileAsync$1(path, options) {
|
|
1187
|
-
return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
|
|
1188
|
-
if (err) {
|
|
1189
|
-
reject(err);
|
|
1190
|
-
}
|
|
1191
|
-
resolve(data);
|
|
1192
|
-
}));
|
|
1193
|
-
}
|
|
1194
1183
|
/**
|
|
1195
1184
|
* Does a request to the authentication provider that results in a file path.
|
|
1196
1185
|
*/
|
|
@@ -1211,6 +1200,43 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
1211
1200
|
throw Error(`Invalid www-authenticate header format: ${authHeader}`);
|
|
1212
1201
|
}
|
|
1213
1202
|
}
|
|
1203
|
+
function platformToFilePath() {
|
|
1204
|
+
switch (process.platform) {
|
|
1205
|
+
case "win32":
|
|
1206
|
+
if (!process.env.PROGRAMDATA) {
|
|
1207
|
+
throw new Error(`${msiName$4}: PROGRAMDATA environment variable has no value.`);
|
|
1208
|
+
}
|
|
1209
|
+
return `${process.env.PROGRAMDATA}\\AzureConnectedMachineAgent\\Tokens`;
|
|
1210
|
+
case "linux":
|
|
1211
|
+
return "/var/opt/azcmagent/tokens";
|
|
1212
|
+
default:
|
|
1213
|
+
throw new Error(`${msiName$4}: Unsupported platform ${process.platform}.`);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Validates that a given Azure Arc MSI file path is valid for use.
|
|
1218
|
+
*
|
|
1219
|
+
* A valid file will:
|
|
1220
|
+
* 1. Be in the expected path for the current platform.
|
|
1221
|
+
* 2. Have a `.key` extension.
|
|
1222
|
+
* 3. Be at most 4096 bytes in size.
|
|
1223
|
+
*/
|
|
1224
|
+
function validateKeyFile(filePath) {
|
|
1225
|
+
if (!filePath) {
|
|
1226
|
+
throw new Error(`${msiName$4}: Failed to find the token file.`);
|
|
1227
|
+
}
|
|
1228
|
+
if (!filePath.endsWith(".key")) {
|
|
1229
|
+
throw new Error(`${msiName$4}: unexpected file path from HIMDS service: ${filePath}.`);
|
|
1230
|
+
}
|
|
1231
|
+
const expectedPath = platformToFilePath();
|
|
1232
|
+
if (!filePath.startsWith(expectedPath)) {
|
|
1233
|
+
throw new Error(`${msiName$4}: unexpected file path from HIMDS service: ${filePath}.`);
|
|
1234
|
+
}
|
|
1235
|
+
const stats = fs$1.statSync(filePath);
|
|
1236
|
+
if (stats.size > 4096) {
|
|
1237
|
+
throw new Error(`${msiName$4}: The file at ${filePath} is larger than expected at ${stats.size} bytes.`);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1214
1240
|
/**
|
|
1215
1241
|
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
|
|
1216
1242
|
*/
|
|
@@ -1240,10 +1266,8 @@ const arcMsi = {
|
|
|
1240
1266
|
logger$m.info(`${msiName$4}: Authenticating.`);
|
|
1241
1267
|
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true });
|
|
1242
1268
|
const filePath = await filePathRequest(identityClient, requestOptions);
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
}
|
|
1246
|
-
const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
|
|
1269
|
+
validateKeyFile(filePath);
|
|
1270
|
+
const key = await fs$1.promises.readFile(filePath, { encoding: "utf-8" });
|
|
1247
1271
|
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
|
1248
1272
|
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
|
|
1249
1273
|
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
@@ -1907,7 +1931,7 @@ function calculateRegionalAuthority(regionalAuthority) {
|
|
|
1907
1931
|
// Copyright (c) Microsoft Corporation.
|
|
1908
1932
|
// Licensed under the MIT license.
|
|
1909
1933
|
/**
|
|
1910
|
-
* The logger
|
|
1934
|
+
* The default logger used if no logger was passed in by the credential.
|
|
1911
1935
|
*/
|
|
1912
1936
|
const msalLogger = credentialLogger("MsalClient");
|
|
1913
1937
|
/**
|
|
@@ -1919,10 +1943,10 @@ const msalLogger = credentialLogger("MsalClient");
|
|
|
1919
1943
|
* @returns The MSAL configuration object.
|
|
1920
1944
|
*/
|
|
1921
1945
|
function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) {
|
|
1922
|
-
var _a, _b, _c;
|
|
1923
|
-
const resolvedTenant = resolveTenantId(msalLogger, tenantId, clientId);
|
|
1946
|
+
var _a, _b, _c, _d;
|
|
1947
|
+
const resolvedTenant = resolveTenantId((_a = msalClientOptions.logger) !== null && _a !== void 0 ? _a : msalLogger, tenantId, clientId);
|
|
1924
1948
|
// TODO: move and reuse getIdentityClientAuthorityHost
|
|
1925
|
-
const authority = getAuthority(resolvedTenant, (
|
|
1949
|
+
const authority = getAuthority(resolvedTenant, (_b = msalClientOptions.authorityHost) !== null && _b !== void 0 ? _b : process.env.AZURE_AUTHORITY_HOST);
|
|
1926
1950
|
const httpClient = new IdentityClient(Object.assign(Object.assign({}, msalClientOptions.tokenCredentialOptions), { authorityHost: authority, loggingOptions: msalClientOptions.loggingOptions }));
|
|
1927
1951
|
const msalConfig = {
|
|
1928
1952
|
auth: {
|
|
@@ -1933,9 +1957,9 @@ function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) {
|
|
|
1933
1957
|
system: {
|
|
1934
1958
|
networkClient: httpClient,
|
|
1935
1959
|
loggerOptions: {
|
|
1936
|
-
loggerCallback: defaultLoggerCallback((
|
|
1960
|
+
loggerCallback: defaultLoggerCallback((_c = msalClientOptions.logger) !== null && _c !== void 0 ? _c : msalLogger),
|
|
1937
1961
|
logLevel: getMSALLogLevel(logger$r.getLogLevel()),
|
|
1938
|
-
piiLoggingEnabled: (
|
|
1962
|
+
piiLoggingEnabled: (_d = msalClientOptions.loggingOptions) === null || _d === void 0 ? void 0 : _d.enableUnsafeSupportLogging,
|
|
1939
1963
|
},
|
|
1940
1964
|
},
|
|
1941
1965
|
};
|
|
@@ -1952,23 +1976,25 @@ function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) {
|
|
|
1952
1976
|
* @public
|
|
1953
1977
|
*/
|
|
1954
1978
|
function createMsalClient(clientId, tenantId, createMsalClientOptions = {}) {
|
|
1979
|
+
var _a;
|
|
1955
1980
|
const state = {
|
|
1956
1981
|
msalConfig: generateMsalConfiguration(clientId, tenantId, createMsalClientOptions),
|
|
1957
1982
|
cachedAccount: createMsalClientOptions.authenticationRecord
|
|
1958
1983
|
? publicToMsal(createMsalClientOptions.authenticationRecord)
|
|
1959
1984
|
: null,
|
|
1960
1985
|
pluginConfiguration: msalPlugins.generatePluginConfiguration(createMsalClientOptions),
|
|
1986
|
+
logger: (_a = createMsalClientOptions.logger) !== null && _a !== void 0 ? _a : msalLogger,
|
|
1961
1987
|
};
|
|
1962
1988
|
const publicApps = new Map();
|
|
1963
1989
|
async function getPublicApp(options = {}) {
|
|
1964
1990
|
const appKey = options.enableCae ? "CAE" : "default";
|
|
1965
1991
|
let publicClientApp = publicApps.get(appKey);
|
|
1966
1992
|
if (publicClientApp) {
|
|
1967
|
-
|
|
1993
|
+
state.logger.getToken.info("Existing PublicClientApplication found in cache, returning it.");
|
|
1968
1994
|
return publicClientApp;
|
|
1969
1995
|
}
|
|
1970
1996
|
// Initialize a new app and cache it
|
|
1971
|
-
|
|
1997
|
+
state.logger.getToken.info(`Creating new PublicClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`);
|
|
1972
1998
|
const cachePlugin = options.enableCae
|
|
1973
1999
|
? state.pluginConfiguration.cache.cachePluginCae
|
|
1974
2000
|
: state.pluginConfiguration.cache.cachePlugin;
|
|
@@ -1982,11 +2008,11 @@ function createMsalClient(clientId, tenantId, createMsalClientOptions = {}) {
|
|
|
1982
2008
|
const appKey = options.enableCae ? "CAE" : "default";
|
|
1983
2009
|
let confidentialClientApp = confidentialApps.get(appKey);
|
|
1984
2010
|
if (confidentialClientApp) {
|
|
1985
|
-
|
|
2011
|
+
state.logger.getToken.info("Existing ConfidentialClientApplication found in cache, returning it.");
|
|
1986
2012
|
return confidentialClientApp;
|
|
1987
2013
|
}
|
|
1988
2014
|
// Initialize a new app and cache it
|
|
1989
|
-
|
|
2015
|
+
state.logger.getToken.info(`Creating new ConfidentialClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`);
|
|
1990
2016
|
const cachePlugin = options.enableCae
|
|
1991
2017
|
? state.pluginConfiguration.cache.cachePluginCae
|
|
1992
2018
|
: state.pluginConfiguration.cache.cachePlugin;
|
|
@@ -1997,14 +2023,15 @@ function createMsalClient(clientId, tenantId, createMsalClientOptions = {}) {
|
|
|
1997
2023
|
}
|
|
1998
2024
|
async function getTokenSilent(app, scopes, options = {}) {
|
|
1999
2025
|
if (state.cachedAccount === null) {
|
|
2000
|
-
|
|
2026
|
+
state.logger.getToken.info("No cached account found in local state, attempting to load it from MSAL cache.");
|
|
2001
2027
|
const cache = app.getTokenCache();
|
|
2002
2028
|
const accounts = await cache.getAllAccounts();
|
|
2003
2029
|
if (accounts === undefined || accounts.length === 0) {
|
|
2004
2030
|
throw new AuthenticationRequiredError({ scopes });
|
|
2005
2031
|
}
|
|
2006
2032
|
if (accounts.length > 1) {
|
|
2007
|
-
|
|
2033
|
+
state.logger
|
|
2034
|
+
.info(`More than one account was found authenticated for this Client ID and Tenant ID.
|
|
2008
2035
|
However, no "authenticationRecord" has been provided for this credential,
|
|
2009
2036
|
therefore we're unable to pick between these accounts.
|
|
2010
2037
|
A new login attempt will be requested, to ensure the correct account is picked.
|
|
@@ -2028,7 +2055,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2028
2055
|
silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
|
|
2029
2056
|
}
|
|
2030
2057
|
}
|
|
2031
|
-
|
|
2058
|
+
state.logger.getToken.info("Attempting to acquire token silently");
|
|
2032
2059
|
return app.acquireTokenSilent(silentRequest);
|
|
2033
2060
|
}
|
|
2034
2061
|
/**
|
|
@@ -2071,14 +2098,14 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2071
2098
|
// At this point we should have a token, process it
|
|
2072
2099
|
ensureValidMsalToken(scopes, response, options);
|
|
2073
2100
|
state.cachedAccount = (_a = response === null || response === void 0 ? void 0 : response.account) !== null && _a !== void 0 ? _a : null;
|
|
2074
|
-
|
|
2101
|
+
state.logger.getToken.info(formatSuccess(scopes));
|
|
2075
2102
|
return {
|
|
2076
2103
|
token: response.accessToken,
|
|
2077
2104
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
2078
2105
|
};
|
|
2079
2106
|
}
|
|
2080
2107
|
async function getTokenByClientSecret(scopes, clientSecret, options = {}) {
|
|
2081
|
-
|
|
2108
|
+
state.logger.getToken.info(`Attempting to acquire token using client secret`);
|
|
2082
2109
|
state.msalConfig.auth.clientSecret = clientSecret;
|
|
2083
2110
|
const msalApp = await getConfidentialApp(options);
|
|
2084
2111
|
try {
|
|
@@ -2089,7 +2116,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2089
2116
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
2090
2117
|
});
|
|
2091
2118
|
ensureValidMsalToken(scopes, response, options);
|
|
2092
|
-
|
|
2119
|
+
state.logger.getToken.info(formatSuccess(scopes));
|
|
2093
2120
|
return {
|
|
2094
2121
|
token: response.accessToken,
|
|
2095
2122
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
@@ -2100,7 +2127,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2100
2127
|
}
|
|
2101
2128
|
}
|
|
2102
2129
|
async function getTokenByClientAssertion(scopes, clientAssertion, options = {}) {
|
|
2103
|
-
|
|
2130
|
+
state.logger.getToken.info(`Attempting to acquire token using client assertion`);
|
|
2104
2131
|
state.msalConfig.auth.clientAssertion = clientAssertion;
|
|
2105
2132
|
const msalApp = await getConfidentialApp(options);
|
|
2106
2133
|
try {
|
|
@@ -2112,7 +2139,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2112
2139
|
clientAssertion,
|
|
2113
2140
|
});
|
|
2114
2141
|
ensureValidMsalToken(scopes, response, options);
|
|
2115
|
-
|
|
2142
|
+
state.logger.getToken.info(formatSuccess(scopes));
|
|
2116
2143
|
return {
|
|
2117
2144
|
token: response.accessToken,
|
|
2118
2145
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
@@ -2123,7 +2150,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2123
2150
|
}
|
|
2124
2151
|
}
|
|
2125
2152
|
async function getTokenByClientCertificate(scopes, certificate, options = {}) {
|
|
2126
|
-
|
|
2153
|
+
state.logger.getToken.info(`Attempting to acquire token using client certificate`);
|
|
2127
2154
|
state.msalConfig.auth.clientCertificate = certificate;
|
|
2128
2155
|
const msalApp = await getConfidentialApp(options);
|
|
2129
2156
|
try {
|
|
@@ -2134,7 +2161,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2134
2161
|
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
2135
2162
|
});
|
|
2136
2163
|
ensureValidMsalToken(scopes, response, options);
|
|
2137
|
-
|
|
2164
|
+
state.logger.getToken.info(formatSuccess(scopes));
|
|
2138
2165
|
return {
|
|
2139
2166
|
token: response.accessToken,
|
|
2140
2167
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
@@ -2145,7 +2172,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2145
2172
|
}
|
|
2146
2173
|
}
|
|
2147
2174
|
async function getTokenByDeviceCode(scopes, deviceCodeCallback, options = {}) {
|
|
2148
|
-
|
|
2175
|
+
state.logger.getToken.info(`Attempting to acquire token using device code`);
|
|
2149
2176
|
const msalApp = await getPublicApp(options);
|
|
2150
2177
|
return withSilentAuthentication(msalApp, scopes, options, () => {
|
|
2151
2178
|
var _a, _b;
|
|
@@ -2165,18 +2192,56 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
2165
2192
|
return deviceCodeRequest;
|
|
2166
2193
|
});
|
|
2167
2194
|
}
|
|
2195
|
+
async function getTokenByUsernamePassword(scopes, username, password, options = {}) {
|
|
2196
|
+
state.logger.getToken.info(`Attempting to acquire token using username and password`);
|
|
2197
|
+
const msalApp = await getPublicApp(options);
|
|
2198
|
+
return withSilentAuthentication(msalApp, scopes, options, () => {
|
|
2199
|
+
const requestOptions = {
|
|
2200
|
+
scopes,
|
|
2201
|
+
username,
|
|
2202
|
+
password,
|
|
2203
|
+
authority: state.msalConfig.auth.authority,
|
|
2204
|
+
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
2205
|
+
};
|
|
2206
|
+
return msalApp.acquireTokenByUsernamePassword(requestOptions);
|
|
2207
|
+
});
|
|
2208
|
+
}
|
|
2168
2209
|
function getActiveAccount() {
|
|
2169
2210
|
if (!state.cachedAccount) {
|
|
2170
2211
|
return undefined;
|
|
2171
2212
|
}
|
|
2172
2213
|
return msalToPublic(clientId, state.cachedAccount);
|
|
2173
2214
|
}
|
|
2215
|
+
async function getTokenByAuthorizationCode(scopes, redirectUri, authorizationCode, clientSecret, options = {}) {
|
|
2216
|
+
state.logger.getToken.info(`Attempting to acquire token using authorization code`);
|
|
2217
|
+
let msalApp;
|
|
2218
|
+
if (clientSecret) {
|
|
2219
|
+
// If a client secret is provided, we need to use a confidential client application
|
|
2220
|
+
// See https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow#request-an-access-token-with-a-client_secret
|
|
2221
|
+
state.msalConfig.auth.clientSecret = clientSecret;
|
|
2222
|
+
msalApp = await getConfidentialApp(options);
|
|
2223
|
+
}
|
|
2224
|
+
else {
|
|
2225
|
+
msalApp = await getPublicApp(options);
|
|
2226
|
+
}
|
|
2227
|
+
return withSilentAuthentication(msalApp, scopes, options, () => {
|
|
2228
|
+
return msalApp.acquireTokenByCode({
|
|
2229
|
+
scopes,
|
|
2230
|
+
redirectUri,
|
|
2231
|
+
code: authorizationCode,
|
|
2232
|
+
authority: state.msalConfig.auth.authority,
|
|
2233
|
+
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
2234
|
+
});
|
|
2235
|
+
});
|
|
2236
|
+
}
|
|
2174
2237
|
return {
|
|
2175
2238
|
getActiveAccount,
|
|
2176
2239
|
getTokenByClientSecret,
|
|
2177
2240
|
getTokenByClientAssertion,
|
|
2178
2241
|
getTokenByClientCertificate,
|
|
2179
2242
|
getTokenByDeviceCode,
|
|
2243
|
+
getTokenByUsernamePassword,
|
|
2244
|
+
getTokenByAuthorizationCode,
|
|
2180
2245
|
};
|
|
2181
2246
|
}
|
|
2182
2247
|
|
|
@@ -3455,114 +3520,422 @@ class ClientSecretCredential {
|
|
|
3455
3520
|
|
|
3456
3521
|
// Copyright (c) Microsoft Corporation.
|
|
3457
3522
|
// Licensed under the MIT license.
|
|
3523
|
+
const logger$7 = credentialLogger("UsernamePasswordCredential");
|
|
3458
3524
|
/**
|
|
3459
|
-
*
|
|
3460
|
-
*
|
|
3461
|
-
*
|
|
3462
|
-
*
|
|
3463
|
-
* which includes handlers for successful responses and errors.
|
|
3464
|
-
*
|
|
3465
|
-
* @internal
|
|
3525
|
+
* Enables authentication to Microsoft Entra ID with a user's
|
|
3526
|
+
* username and password. This credential requires a high degree of
|
|
3527
|
+
* trust so you should only use it when other, more secure credential
|
|
3528
|
+
* types can't be used.
|
|
3466
3529
|
*/
|
|
3467
|
-
class
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
this.enableMsaPassthrough = (_c = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough;
|
|
3483
|
-
this.parentWindowHandle = (_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.parentWindowHandle;
|
|
3484
|
-
// If persistence has been configured
|
|
3485
|
-
if (persistenceProvider !== undefined && ((_e = options.tokenCachePersistenceOptions) === null || _e === void 0 ? void 0 : _e.enabled)) {
|
|
3486
|
-
const cacheBaseName = options.tokenCachePersistenceOptions.name || DEFAULT_TOKEN_CACHE_NAME;
|
|
3487
|
-
const nonCaeOptions = Object.assign({ name: `${cacheBaseName}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
|
|
3488
|
-
const caeOptions = Object.assign({ name: `${cacheBaseName}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
|
|
3489
|
-
this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
|
|
3490
|
-
this.createCachePluginCae = () => persistenceProvider(caeOptions);
|
|
3491
|
-
}
|
|
3492
|
-
else if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
|
|
3493
|
-
throw new Error([
|
|
3494
|
-
"Persistent token caching was requested, but no persistence provider was configured.",
|
|
3495
|
-
"You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
|
|
3496
|
-
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
|
|
3497
|
-
"`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
|
|
3498
|
-
].join(" "));
|
|
3499
|
-
}
|
|
3500
|
-
// If broker has not been configured
|
|
3501
|
-
if (!hasNativeBroker() && this.enableBroker) {
|
|
3502
|
-
throw new Error([
|
|
3503
|
-
"Broker for WAM was requested to be enabled, but no native broker was configured.",
|
|
3504
|
-
"You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
|
|
3505
|
-
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
|
|
3506
|
-
"`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
|
|
3507
|
-
].join(" "));
|
|
3530
|
+
class UsernamePasswordCredential {
|
|
3531
|
+
/**
|
|
3532
|
+
* Creates an instance of the UsernamePasswordCredential with the details
|
|
3533
|
+
* needed to authenticate against Microsoft Entra ID with a username
|
|
3534
|
+
* and password.
|
|
3535
|
+
*
|
|
3536
|
+
* @param tenantId - The Microsoft Entra tenant (directory).
|
|
3537
|
+
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
3538
|
+
* @param username - The user account's e-mail address (user name).
|
|
3539
|
+
* @param password - The user account's account password
|
|
3540
|
+
* @param options - Options for configuring the client which makes the authentication request.
|
|
3541
|
+
*/
|
|
3542
|
+
constructor(tenantId, clientId, username, password, options = {}) {
|
|
3543
|
+
if (!tenantId || !clientId || !username || !password) {
|
|
3544
|
+
throw new Error("UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.");
|
|
3508
3545
|
}
|
|
3509
|
-
this.
|
|
3546
|
+
this.tenantId = tenantId;
|
|
3547
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3548
|
+
this.username = username;
|
|
3549
|
+
this.password = password;
|
|
3550
|
+
this.msalClient = createMsalClient(clientId, this.tenantId, Object.assign(Object.assign({}, options), { tokenCredentialOptions: options !== null && options !== void 0 ? options : {} }));
|
|
3510
3551
|
}
|
|
3511
3552
|
/**
|
|
3512
|
-
*
|
|
3553
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3554
|
+
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3555
|
+
*
|
|
3556
|
+
* If the user provided the option `disableAutomaticAuthentication`,
|
|
3557
|
+
* once the token can't be retrieved silently,
|
|
3558
|
+
* this method won't attempt to request user interaction to retrieve the token.
|
|
3559
|
+
*
|
|
3560
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
3561
|
+
* @param options - The options used to configure any requests this
|
|
3562
|
+
* TokenCredential implementation might make.
|
|
3513
3563
|
*/
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
|
|
3521
|
-
const clientCapabilities = [];
|
|
3522
|
-
return {
|
|
3523
|
-
auth: {
|
|
3524
|
-
clientId,
|
|
3525
|
-
authority,
|
|
3526
|
-
knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
|
|
3527
|
-
clientCapabilities,
|
|
3528
|
-
},
|
|
3529
|
-
// Cache is defined in this.prepare();
|
|
3530
|
-
system: {
|
|
3531
|
-
networkClient: this.identityClient,
|
|
3532
|
-
loggerOptions: {
|
|
3533
|
-
loggerCallback: defaultLoggerCallback(options.logger),
|
|
3534
|
-
logLevel: getMSALLogLevel(logger$r.getLogLevel()),
|
|
3535
|
-
piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
|
|
3536
|
-
},
|
|
3537
|
-
},
|
|
3538
|
-
};
|
|
3564
|
+
async getToken(scopes, options = {}) {
|
|
3565
|
+
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3566
|
+
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$7);
|
|
3567
|
+
const arrayScopes = ensureScopes(scopes);
|
|
3568
|
+
return this.msalClient.getTokenByUsernamePassword(arrayScopes, this.username, this.password, newOptions);
|
|
3569
|
+
});
|
|
3539
3570
|
}
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3573
|
+
// Copyright (c) Microsoft Corporation.
|
|
3574
|
+
// Licensed under the MIT license.
|
|
3575
|
+
/**
|
|
3576
|
+
* Contains the list of all supported environment variable names so that an
|
|
3577
|
+
* appropriate error message can be generated when no credentials can be
|
|
3578
|
+
* configured.
|
|
3579
|
+
*
|
|
3580
|
+
* @internal
|
|
3581
|
+
*/
|
|
3582
|
+
const AllSupportedEnvironmentVariables = [
|
|
3583
|
+
"AZURE_TENANT_ID",
|
|
3584
|
+
"AZURE_CLIENT_ID",
|
|
3585
|
+
"AZURE_CLIENT_SECRET",
|
|
3586
|
+
"AZURE_CLIENT_CERTIFICATE_PATH",
|
|
3587
|
+
"AZURE_CLIENT_CERTIFICATE_PASSWORD",
|
|
3588
|
+
"AZURE_USERNAME",
|
|
3589
|
+
"AZURE_PASSWORD",
|
|
3590
|
+
"AZURE_ADDITIONALLY_ALLOWED_TENANTS",
|
|
3591
|
+
];
|
|
3592
|
+
function getAdditionallyAllowedTenants() {
|
|
3593
|
+
var _a;
|
|
3594
|
+
const additionallyAllowedValues = (_a = process.env.AZURE_ADDITIONALLY_ALLOWED_TENANTS) !== null && _a !== void 0 ? _a : "";
|
|
3595
|
+
return additionallyAllowedValues.split(";");
|
|
3596
|
+
}
|
|
3597
|
+
const credentialName$2 = "EnvironmentCredential";
|
|
3598
|
+
const logger$6 = credentialLogger(credentialName$2);
|
|
3599
|
+
/**
|
|
3600
|
+
* Enables authentication to Microsoft Entra ID using a client secret or certificate, or as a user
|
|
3601
|
+
* with a username and password.
|
|
3602
|
+
*/
|
|
3603
|
+
class EnvironmentCredential {
|
|
3604
|
+
/**
|
|
3605
|
+
* Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables.
|
|
3606
|
+
*
|
|
3607
|
+
* Required environment variables:
|
|
3608
|
+
* - `AZURE_TENANT_ID`: The Microsoft Entra tenant (directory) ID.
|
|
3609
|
+
* - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant.
|
|
3610
|
+
*
|
|
3611
|
+
* If setting the AZURE_TENANT_ID, then you can also set the additionally allowed tenants
|
|
3612
|
+
* - `AZURE_ADDITIONALLY_ALLOWED_TENANTS`: For multi-tenant applications, specifies additional tenants for which the credential may acquire tokens with a single semicolon delimited string. Use * to allow all tenants.
|
|
3613
|
+
*
|
|
3614
|
+
* Environment variables used for client credential authentication:
|
|
3615
|
+
* - `AZURE_CLIENT_SECRET`: A client secret that was generated for the App Registration.
|
|
3616
|
+
* - `AZURE_CLIENT_CERTIFICATE_PATH`: The path to a PEM certificate to use during the authentication, instead of the client secret.
|
|
3617
|
+
* - `AZURE_CLIENT_CERTIFICATE_PASSWORD`: (optional) password for the certificate file.
|
|
3618
|
+
*
|
|
3619
|
+
* Alternatively, users can provide environment variables for username and password authentication:
|
|
3620
|
+
* - `AZURE_USERNAME`: Username to authenticate with.
|
|
3621
|
+
* - `AZURE_PASSWORD`: Password to authenticate with.
|
|
3622
|
+
*
|
|
3623
|
+
* If the environment variables required to perform the authentication are missing, a {@link CredentialUnavailableError} will be thrown.
|
|
3624
|
+
* If the authentication fails, or if there's an unknown error, an {@link AuthenticationError} will be thrown.
|
|
3625
|
+
*
|
|
3626
|
+
* @param options - Options for configuring the client which makes the authentication request.
|
|
3627
|
+
*/
|
|
3628
|
+
constructor(options) {
|
|
3629
|
+
// Keep track of any missing environment variables for error details
|
|
3630
|
+
this._credential = undefined;
|
|
3631
|
+
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
|
|
3632
|
+
logger$6.info(`Found the following environment variables: ${assigned}`);
|
|
3633
|
+
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
3634
|
+
const additionallyAllowedTenantIds = getAdditionallyAllowedTenants();
|
|
3635
|
+
const newOptions = Object.assign(Object.assign({}, options), { additionallyAllowedTenantIds });
|
|
3636
|
+
if (tenantId) {
|
|
3637
|
+
checkTenantId(logger$6, tenantId);
|
|
3544
3638
|
}
|
|
3545
|
-
|
|
3546
|
-
|
|
3639
|
+
if (tenantId && clientId && clientSecret) {
|
|
3640
|
+
logger$6.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
|
|
3641
|
+
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, newOptions);
|
|
3642
|
+
return;
|
|
3547
3643
|
}
|
|
3548
|
-
|
|
3549
|
-
|
|
3644
|
+
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
|
|
3645
|
+
const certificatePassword = process.env.AZURE_CLIENT_CERTIFICATE_PASSWORD;
|
|
3646
|
+
if (tenantId && clientId && certificatePath) {
|
|
3647
|
+
logger$6.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
|
|
3648
|
+
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath, certificatePassword }, newOptions);
|
|
3649
|
+
return;
|
|
3550
3650
|
}
|
|
3551
|
-
|
|
3552
|
-
|
|
3651
|
+
const username = process.env.AZURE_USERNAME;
|
|
3652
|
+
const password = process.env.AZURE_PASSWORD;
|
|
3653
|
+
if (tenantId && clientId && username && password) {
|
|
3654
|
+
logger$6.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
|
|
3655
|
+
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, newOptions);
|
|
3553
3656
|
}
|
|
3554
3657
|
}
|
|
3555
3658
|
/**
|
|
3556
|
-
*
|
|
3659
|
+
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3660
|
+
*
|
|
3661
|
+
* @param scopes - The list of scopes for which the token will have access.
|
|
3662
|
+
* @param options - Optional parameters. See {@link GetTokenOptions}.
|
|
3557
3663
|
*/
|
|
3558
|
-
async
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3664
|
+
async getToken(scopes, options = {}) {
|
|
3665
|
+
return tracingClient.withSpan(`${credentialName$2}.getToken`, options, async (newOptions) => {
|
|
3666
|
+
if (this._credential) {
|
|
3667
|
+
try {
|
|
3668
|
+
const result = await this._credential.getToken(scopes, newOptions);
|
|
3669
|
+
logger$6.getToken.info(formatSuccess(scopes));
|
|
3670
|
+
return result;
|
|
3671
|
+
}
|
|
3672
|
+
catch (err) {
|
|
3673
|
+
const authenticationError = new AuthenticationError(400, {
|
|
3674
|
+
error: `${credentialName$2} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
|
|
3675
|
+
error_description: err.message.toString().split("More details:").join(""),
|
|
3676
|
+
});
|
|
3677
|
+
logger$6.getToken.info(formatError(scopes, authenticationError));
|
|
3678
|
+
throw authenticationError;
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
throw new CredentialUnavailableError(`${credentialName$2} is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`);
|
|
3682
|
+
});
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
// Copyright (c) Microsoft Corporation.
|
|
3687
|
+
// Licensed under the MIT license.
|
|
3688
|
+
const logger$5 = credentialLogger("DefaultAzureCredential");
|
|
3689
|
+
/**
|
|
3690
|
+
* Creates a {@link ManagedIdentityCredential} from the provided options.
|
|
3691
|
+
* @param options - Options to configure the credential.
|
|
3692
|
+
*
|
|
3693
|
+
* @internal
|
|
3694
|
+
*/
|
|
3695
|
+
function createDefaultManagedIdentityCredential(options = {}) {
|
|
3696
|
+
var _a, _b, _c, _d;
|
|
3697
|
+
(_a = options.retryOptions) !== null && _a !== void 0 ? _a : (options.retryOptions = {
|
|
3698
|
+
maxRetries: 5,
|
|
3699
|
+
retryDelayInMs: 800,
|
|
3700
|
+
});
|
|
3701
|
+
const managedIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
|
|
3702
|
+
const workloadIdentityClientId = (_c = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _c !== void 0 ? _c : managedIdentityClientId;
|
|
3703
|
+
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
|
|
3704
|
+
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3705
|
+
const tenantId = (_d = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _d !== void 0 ? _d : process.env.AZURE_TENANT_ID;
|
|
3706
|
+
if (managedResourceId) {
|
|
3707
|
+
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
|
|
3708
|
+
return new ManagedIdentityCredential(managedIdentityResourceIdOptions);
|
|
3709
|
+
}
|
|
3710
|
+
if (workloadFile && workloadIdentityClientId) {
|
|
3711
|
+
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId: tenantId });
|
|
3712
|
+
return new ManagedIdentityCredential(workloadIdentityClientId, workloadIdentityCredentialOptions);
|
|
3713
|
+
}
|
|
3714
|
+
if (managedIdentityClientId) {
|
|
3715
|
+
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
|
|
3716
|
+
return new ManagedIdentityCredential(managedIdentityClientOptions);
|
|
3717
|
+
}
|
|
3718
|
+
// We may be able to return a UnavailableCredential here, but that may be a breaking change
|
|
3719
|
+
return new ManagedIdentityCredential(options);
|
|
3720
|
+
}
|
|
3721
|
+
/**
|
|
3722
|
+
* Creates a {@link WorkloadIdentityCredential} from the provided options.
|
|
3723
|
+
* @param options - Options to configure the credential.
|
|
3724
|
+
*
|
|
3725
|
+
* @internal
|
|
3726
|
+
*/
|
|
3727
|
+
function createDefaultWorkloadIdentityCredential(options) {
|
|
3728
|
+
var _a, _b, _c;
|
|
3729
|
+
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
|
|
3730
|
+
const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
|
|
3731
|
+
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3732
|
+
const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
|
|
3733
|
+
if (workloadFile && workloadIdentityClientId) {
|
|
3734
|
+
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId, clientId: workloadIdentityClientId, tokenFilePath: workloadFile });
|
|
3735
|
+
return new WorkloadIdentityCredential(workloadIdentityCredentialOptions);
|
|
3736
|
+
}
|
|
3737
|
+
if (tenantId) {
|
|
3738
|
+
const workloadIdentityClientTenantOptions = Object.assign(Object.assign({}, options), { tenantId });
|
|
3739
|
+
return new WorkloadIdentityCredential(workloadIdentityClientTenantOptions);
|
|
3740
|
+
}
|
|
3741
|
+
// We may be able to return a UnavailableCredential here, but that may be a breaking change
|
|
3742
|
+
return new WorkloadIdentityCredential(options);
|
|
3743
|
+
}
|
|
3744
|
+
/**
|
|
3745
|
+
* Creates a {@link AzureDeveloperCliCredential} from the provided options.
|
|
3746
|
+
* @param options - Options to configure the credential.
|
|
3747
|
+
*
|
|
3748
|
+
* @internal
|
|
3749
|
+
*/
|
|
3750
|
+
function createDefaultAzureDeveloperCliCredential(options = {}) {
|
|
3751
|
+
const processTimeoutInMs = options.processTimeoutInMs;
|
|
3752
|
+
return new AzureDeveloperCliCredential(Object.assign({ processTimeoutInMs }, options));
|
|
3753
|
+
}
|
|
3754
|
+
/**
|
|
3755
|
+
* Creates a {@link AzureCliCredential} from the provided options.
|
|
3756
|
+
* @param options - Options to configure the credential.
|
|
3757
|
+
*
|
|
3758
|
+
* @internal
|
|
3759
|
+
*/
|
|
3760
|
+
function createDefaultAzureCliCredential(options = {}) {
|
|
3761
|
+
const processTimeoutInMs = options.processTimeoutInMs;
|
|
3762
|
+
return new AzureCliCredential(Object.assign({ processTimeoutInMs }, options));
|
|
3763
|
+
}
|
|
3764
|
+
/**
|
|
3765
|
+
* Creates a {@link AzurePowerShellCredential} from the provided options.
|
|
3766
|
+
* @param options - Options to configure the credential.
|
|
3767
|
+
*
|
|
3768
|
+
* @internal
|
|
3769
|
+
*/
|
|
3770
|
+
function createDefaultAzurePowershellCredential(options = {}) {
|
|
3771
|
+
const processTimeoutInMs = options.processTimeoutInMs;
|
|
3772
|
+
return new AzurePowerShellCredential(Object.assign({ processTimeoutInMs }, options));
|
|
3773
|
+
}
|
|
3774
|
+
/**
|
|
3775
|
+
* Creates an {@link EnvironmentCredential} from the provided options.
|
|
3776
|
+
* @param options - Options to configure the credential.
|
|
3777
|
+
*
|
|
3778
|
+
* @internal
|
|
3779
|
+
*/
|
|
3780
|
+
function createEnvironmentCredential(options = {}) {
|
|
3781
|
+
return new EnvironmentCredential(options);
|
|
3782
|
+
}
|
|
3783
|
+
/**
|
|
3784
|
+
* A no-op credential that logs the reason it was skipped if getToken is called.
|
|
3785
|
+
* @internal
|
|
3786
|
+
*/
|
|
3787
|
+
class UnavailableDefaultCredential {
|
|
3788
|
+
constructor(credentialName, message) {
|
|
3789
|
+
this.credentialName = credentialName;
|
|
3790
|
+
this.credentialUnavailableErrorMessage = message;
|
|
3791
|
+
}
|
|
3792
|
+
getToken() {
|
|
3793
|
+
logger$5.getToken.info(`Skipping ${this.credentialName}, reason: ${this.credentialUnavailableErrorMessage}`);
|
|
3794
|
+
return Promise.resolve(null);
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
/**
|
|
3798
|
+
* Provides a default {@link ChainedTokenCredential} configuration that should
|
|
3799
|
+
* work for most applications that use the Azure SDK.
|
|
3800
|
+
*/
|
|
3801
|
+
class DefaultAzureCredential extends ChainedTokenCredential {
|
|
3802
|
+
constructor(options) {
|
|
3803
|
+
const credentialFunctions = [
|
|
3804
|
+
createEnvironmentCredential,
|
|
3805
|
+
createDefaultWorkloadIdentityCredential,
|
|
3806
|
+
createDefaultManagedIdentityCredential,
|
|
3807
|
+
createDefaultAzureCliCredential,
|
|
3808
|
+
createDefaultAzurePowershellCredential,
|
|
3809
|
+
createDefaultAzureDeveloperCliCredential,
|
|
3810
|
+
];
|
|
3811
|
+
// DefaultCredential constructors should not throw, instead throwing on getToken() which is handled by ChainedTokenCredential.
|
|
3812
|
+
// When adding new credentials to the default chain, consider:
|
|
3813
|
+
// 1. Making the constructor parameters required and explicit
|
|
3814
|
+
// 2. Validating any required parameters in the factory function
|
|
3815
|
+
// 3. Returning a UnavailableDefaultCredential from the factory function if a credential is unavailable for any reason
|
|
3816
|
+
const credentials = credentialFunctions.map((createCredentialFn) => {
|
|
3817
|
+
try {
|
|
3818
|
+
return createCredentialFn(options);
|
|
3819
|
+
}
|
|
3820
|
+
catch (err) {
|
|
3821
|
+
logger$5.warning(`Skipped ${createCredentialFn.name} because of an error creating the credential: ${err}`);
|
|
3822
|
+
return new UnavailableDefaultCredential(createCredentialFn.name, err.message);
|
|
3823
|
+
}
|
|
3824
|
+
});
|
|
3825
|
+
super(...credentials);
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3828
|
+
|
|
3829
|
+
// Copyright (c) Microsoft Corporation.
|
|
3830
|
+
// Licensed under the MIT license.
|
|
3831
|
+
/**
|
|
3832
|
+
* MSAL partial base client for Node.js.
|
|
3833
|
+
*
|
|
3834
|
+
* It completes the input configuration with some default values.
|
|
3835
|
+
* It also provides with utility protected methods that can be used from any of the clients,
|
|
3836
|
+
* which includes handlers for successful responses and errors.
|
|
3837
|
+
*
|
|
3838
|
+
* @internal
|
|
3839
|
+
*/
|
|
3840
|
+
class MsalNode {
|
|
3841
|
+
constructor(options) {
|
|
3842
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3843
|
+
this.app = {};
|
|
3844
|
+
this.caeApp = {};
|
|
3845
|
+
this.requiresConfidential = false;
|
|
3846
|
+
this.logger = options.logger;
|
|
3847
|
+
this.msalConfig = this.defaultNodeMsalConfig(options);
|
|
3848
|
+
this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
|
|
3849
|
+
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
|
|
3850
|
+
this.clientId = this.msalConfig.auth.clientId;
|
|
3851
|
+
if (options === null || options === void 0 ? void 0 : options.getAssertion) {
|
|
3852
|
+
this.getAssertion = options.getAssertion;
|
|
3853
|
+
}
|
|
3854
|
+
this.enableBroker = (_b = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _b === void 0 ? void 0 : _b.enabled;
|
|
3855
|
+
this.enableMsaPassthrough = (_c = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough;
|
|
3856
|
+
this.parentWindowHandle = (_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.parentWindowHandle;
|
|
3857
|
+
// If persistence has been configured
|
|
3858
|
+
if (persistenceProvider !== undefined && ((_e = options.tokenCachePersistenceOptions) === null || _e === void 0 ? void 0 : _e.enabled)) {
|
|
3859
|
+
const cacheBaseName = options.tokenCachePersistenceOptions.name || DEFAULT_TOKEN_CACHE_NAME;
|
|
3860
|
+
const nonCaeOptions = Object.assign({ name: `${cacheBaseName}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
|
|
3861
|
+
const caeOptions = Object.assign({ name: `${cacheBaseName}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
|
|
3862
|
+
this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
|
|
3863
|
+
this.createCachePluginCae = () => persistenceProvider(caeOptions);
|
|
3864
|
+
}
|
|
3865
|
+
else if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
|
|
3866
|
+
throw new Error([
|
|
3867
|
+
"Persistent token caching was requested, but no persistence provider was configured.",
|
|
3868
|
+
"You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
|
|
3869
|
+
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
|
|
3870
|
+
"`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
|
|
3871
|
+
].join(" "));
|
|
3872
|
+
}
|
|
3873
|
+
// If broker has not been configured
|
|
3874
|
+
if (!hasNativeBroker() && this.enableBroker) {
|
|
3875
|
+
throw new Error([
|
|
3876
|
+
"Broker for WAM was requested to be enabled, but no native broker was configured.",
|
|
3877
|
+
"You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
|
|
3878
|
+
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
|
|
3879
|
+
"`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
|
|
3880
|
+
].join(" "));
|
|
3881
|
+
}
|
|
3882
|
+
this.azureRegion = calculateRegionalAuthority(options.regionalAuthority);
|
|
3883
|
+
}
|
|
3884
|
+
/**
|
|
3885
|
+
* Generates a MSAL configuration that generally works for Node.js
|
|
3886
|
+
*/
|
|
3887
|
+
defaultNodeMsalConfig(options) {
|
|
3888
|
+
var _a;
|
|
3889
|
+
const clientId = options.clientId || DeveloperSignOnClientId;
|
|
3890
|
+
const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
|
|
3891
|
+
this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
|
|
3892
|
+
const authority = getAuthority(tenantId, this.authorityHost);
|
|
3893
|
+
this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
|
|
3894
|
+
const clientCapabilities = [];
|
|
3895
|
+
return {
|
|
3896
|
+
auth: {
|
|
3897
|
+
clientId,
|
|
3898
|
+
authority,
|
|
3899
|
+
knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
|
|
3900
|
+
clientCapabilities,
|
|
3901
|
+
},
|
|
3902
|
+
// Cache is defined in this.prepare();
|
|
3903
|
+
system: {
|
|
3904
|
+
networkClient: this.identityClient,
|
|
3905
|
+
loggerOptions: {
|
|
3906
|
+
loggerCallback: defaultLoggerCallback(options.logger),
|
|
3907
|
+
logLevel: getMSALLogLevel(logger$r.getLogLevel()),
|
|
3908
|
+
piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
|
|
3909
|
+
},
|
|
3910
|
+
},
|
|
3911
|
+
};
|
|
3912
|
+
}
|
|
3913
|
+
getApp(appType, enableCae) {
|
|
3914
|
+
const app = enableCae ? this.caeApp : this.app;
|
|
3915
|
+
if (appType === "publicFirst") {
|
|
3916
|
+
return (app.public || app.confidential);
|
|
3917
|
+
}
|
|
3918
|
+
else if (appType === "confidentialFirst") {
|
|
3919
|
+
return (app.confidential || app.public);
|
|
3920
|
+
}
|
|
3921
|
+
else if (appType === "confidential") {
|
|
3922
|
+
return app.confidential;
|
|
3923
|
+
}
|
|
3924
|
+
else {
|
|
3925
|
+
return app.public;
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
/**
|
|
3929
|
+
* Prepares the MSAL applications.
|
|
3930
|
+
*/
|
|
3931
|
+
async init(options) {
|
|
3932
|
+
if (options === null || options === void 0 ? void 0 : options.abortSignal) {
|
|
3933
|
+
options.abortSignal.addEventListener("abort", () => {
|
|
3934
|
+
// This will abort any pending request in the IdentityClient,
|
|
3935
|
+
// based on the received or generated correlationId
|
|
3936
|
+
this.identityClient.abortRequests(options.correlationId);
|
|
3937
|
+
});
|
|
3938
|
+
}
|
|
3566
3939
|
const app = (options === null || options === void 0 ? void 0 : options.enableCae) ? this.caeApp : this.app;
|
|
3567
3940
|
if (options === null || options === void 0 ? void 0 : options.enableCae) {
|
|
3568
3941
|
this.msalConfig.auth.clientCapabilities = ["cp1"];
|
|
@@ -3699,409 +4072,68 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
|
3699
4072
|
* `authenticationRecord` parameter. See issue - https://github.com/Azure/azure-sdk-for-js/issues/24349#issuecomment-1496715651
|
|
3700
4073
|
* This workaround serves as a workaround for silent authentication not happening when authenticationRecord is passed.
|
|
3701
4074
|
*/
|
|
3702
|
-
await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
|
|
3703
|
-
const response = (_c = (await ((_b = this.getApp("confidential", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _b === void 0 ? void 0 : _b.acquireTokenSilent(silentRequest)))) !== null && _c !== void 0 ? _c : (await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenSilent(silentRequest));
|
|
3704
|
-
return this.handleResult(scopes, response || undefined);
|
|
3705
|
-
}
|
|
3706
|
-
catch (err) {
|
|
3707
|
-
throw handleMsalError(scopes, err, options);
|
|
3708
|
-
}
|
|
3709
|
-
}
|
|
3710
|
-
/**
|
|
3711
|
-
* Wrapper around each MSAL flow get token operation: doGetToken.
|
|
3712
|
-
* If disableAutomaticAuthentication is sent through the constructor, it will prevent MSAL from requesting the user input.
|
|
3713
|
-
*/
|
|
3714
|
-
async getToken(scopes, options = {}) {
|
|
3715
|
-
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
|
|
3716
|
-
this.tenantId;
|
|
3717
|
-
options.authority = getAuthority(tenantId, this.authorityHost);
|
|
3718
|
-
options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || randomUUID();
|
|
3719
|
-
await this.init(options);
|
|
3720
|
-
try {
|
|
3721
|
-
// MSAL now caches tokens based on their claims,
|
|
3722
|
-
// so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
|
|
3723
|
-
// This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
|
|
3724
|
-
const optionsClaims = options.claims;
|
|
3725
|
-
if (optionsClaims) {
|
|
3726
|
-
this.cachedClaims = optionsClaims;
|
|
3727
|
-
}
|
|
3728
|
-
if (this.cachedClaims && !optionsClaims) {
|
|
3729
|
-
options.claims = this.cachedClaims;
|
|
3730
|
-
}
|
|
3731
|
-
// We don't return the promise since we want to catch errors right here.
|
|
3732
|
-
return await this.getTokenSilent(scopes, options);
|
|
3733
|
-
}
|
|
3734
|
-
catch (err) {
|
|
3735
|
-
if (err.name !== "AuthenticationRequiredError") {
|
|
3736
|
-
throw err;
|
|
3737
|
-
}
|
|
3738
|
-
if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
|
|
3739
|
-
throw new AuthenticationRequiredError({
|
|
3740
|
-
scopes,
|
|
3741
|
-
getTokenOptions: options,
|
|
3742
|
-
message: "Automatic authentication has been disabled. You may call the authentication() method.",
|
|
3743
|
-
});
|
|
3744
|
-
}
|
|
3745
|
-
this.logger.info(`Silent authentication failed, falling back to interactive method.`);
|
|
3746
|
-
return this.doGetToken(scopes, options);
|
|
3747
|
-
}
|
|
3748
|
-
}
|
|
3749
|
-
/**
|
|
3750
|
-
* Handles the MSAL authentication result.
|
|
3751
|
-
* If the result has an account, we update the local account reference.
|
|
3752
|
-
* If the token received is invalid, an error will be thrown depending on what's missing.
|
|
3753
|
-
*/
|
|
3754
|
-
handleResult(scopes, result, getTokenOptions) {
|
|
3755
|
-
if (result === null || result === void 0 ? void 0 : result.account) {
|
|
3756
|
-
this.account = msalToPublic(this.clientId, result.account);
|
|
3757
|
-
}
|
|
3758
|
-
ensureValidMsalToken(scopes, result, getTokenOptions);
|
|
3759
|
-
this.logger.getToken.info(formatSuccess(scopes));
|
|
3760
|
-
return {
|
|
3761
|
-
token: result.accessToken,
|
|
3762
|
-
expiresOnTimestamp: result.expiresOn.getTime(),
|
|
3763
|
-
};
|
|
3764
|
-
}
|
|
3765
|
-
}
|
|
3766
|
-
|
|
3767
|
-
// Copyright (c) Microsoft Corporation.
|
|
3768
|
-
// Licensed under the MIT license.
|
|
3769
|
-
/**
|
|
3770
|
-
* MSAL username and password client. Calls to the MSAL's public application's `acquireTokenByUsernamePassword` during `doGetToken`.
|
|
3771
|
-
* @internal
|
|
3772
|
-
*/
|
|
3773
|
-
class MsalUsernamePassword extends MsalNode {
|
|
3774
|
-
constructor(options) {
|
|
3775
|
-
super(options);
|
|
3776
|
-
this.username = options.username;
|
|
3777
|
-
this.password = options.password;
|
|
3778
|
-
}
|
|
3779
|
-
async doGetToken(scopes, options) {
|
|
3780
|
-
try {
|
|
3781
|
-
const requestOptions = {
|
|
3782
|
-
scopes,
|
|
3783
|
-
username: this.username,
|
|
3784
|
-
password: this.password,
|
|
3785
|
-
correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
|
|
3786
|
-
authority: options === null || options === void 0 ? void 0 : options.authority,
|
|
3787
|
-
claims: options === null || options === void 0 ? void 0 : options.claims,
|
|
3788
|
-
};
|
|
3789
|
-
const result = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenByUsernamePassword(requestOptions);
|
|
3790
|
-
return this.handleResult(scopes, result || undefined);
|
|
3791
|
-
}
|
|
3792
|
-
catch (error) {
|
|
3793
|
-
throw handleMsalError(scopes, error, options);
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
}
|
|
3797
|
-
|
|
3798
|
-
// Copyright (c) Microsoft Corporation.
|
|
3799
|
-
// Licensed under the MIT license.
|
|
3800
|
-
const logger$7 = credentialLogger("UsernamePasswordCredential");
|
|
3801
|
-
/**
|
|
3802
|
-
* Enables authentication to Microsoft Entra ID with a user's
|
|
3803
|
-
* username and password. This credential requires a high degree of
|
|
3804
|
-
* trust so you should only use it when other, more secure credential
|
|
3805
|
-
* types can't be used.
|
|
3806
|
-
*/
|
|
3807
|
-
class UsernamePasswordCredential {
|
|
3808
|
-
/**
|
|
3809
|
-
* Creates an instance of the UsernamePasswordCredential with the details
|
|
3810
|
-
* needed to authenticate against Microsoft Entra ID with a username
|
|
3811
|
-
* and password.
|
|
3812
|
-
*
|
|
3813
|
-
* @param tenantId - The Microsoft Entra tenant (directory).
|
|
3814
|
-
* @param clientId - The client (application) ID of an App Registration in the tenant.
|
|
3815
|
-
* @param username - The user account's e-mail address (user name).
|
|
3816
|
-
* @param password - The user account's account password
|
|
3817
|
-
* @param options - Options for configuring the client which makes the authentication request.
|
|
3818
|
-
*/
|
|
3819
|
-
constructor(tenantId, clientId, username, password, options = {}) {
|
|
3820
|
-
if (!tenantId || !clientId || !username || !password) {
|
|
3821
|
-
throw new Error("UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.");
|
|
3822
|
-
}
|
|
3823
|
-
this.tenantId = tenantId;
|
|
3824
|
-
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
3825
|
-
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger: logger$7,
|
|
3826
|
-
clientId,
|
|
3827
|
-
tenantId,
|
|
3828
|
-
username,
|
|
3829
|
-
password, tokenCredentialOptions: options || {} }));
|
|
3830
|
-
}
|
|
3831
|
-
/**
|
|
3832
|
-
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
3833
|
-
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
|
|
3834
|
-
*
|
|
3835
|
-
* If the user provided the option `disableAutomaticAuthentication`,
|
|
3836
|
-
* once the token can't be retrieved silently,
|
|
3837
|
-
* this method won't attempt to request user interaction to retrieve the token.
|
|
3838
|
-
*
|
|
3839
|
-
* @param scopes - The list of scopes for which the token will have access.
|
|
3840
|
-
* @param options - The options used to configure any requests this
|
|
3841
|
-
* TokenCredential implementation might make.
|
|
3842
|
-
*/
|
|
3843
|
-
async getToken(scopes, options = {}) {
|
|
3844
|
-
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
|
|
3845
|
-
newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$7);
|
|
3846
|
-
const arrayScopes = ensureScopes(scopes);
|
|
3847
|
-
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3848
|
-
});
|
|
3849
|
-
}
|
|
3850
|
-
}
|
|
3851
|
-
|
|
3852
|
-
// Copyright (c) Microsoft Corporation.
|
|
3853
|
-
// Licensed under the MIT license.
|
|
3854
|
-
/**
|
|
3855
|
-
* Contains the list of all supported environment variable names so that an
|
|
3856
|
-
* appropriate error message can be generated when no credentials can be
|
|
3857
|
-
* configured.
|
|
3858
|
-
*
|
|
3859
|
-
* @internal
|
|
3860
|
-
*/
|
|
3861
|
-
const AllSupportedEnvironmentVariables = [
|
|
3862
|
-
"AZURE_TENANT_ID",
|
|
3863
|
-
"AZURE_CLIENT_ID",
|
|
3864
|
-
"AZURE_CLIENT_SECRET",
|
|
3865
|
-
"AZURE_CLIENT_CERTIFICATE_PATH",
|
|
3866
|
-
"AZURE_CLIENT_CERTIFICATE_PASSWORD",
|
|
3867
|
-
"AZURE_USERNAME",
|
|
3868
|
-
"AZURE_PASSWORD",
|
|
3869
|
-
"AZURE_ADDITIONALLY_ALLOWED_TENANTS",
|
|
3870
|
-
];
|
|
3871
|
-
function getAdditionallyAllowedTenants() {
|
|
3872
|
-
var _a;
|
|
3873
|
-
const additionallyAllowedValues = (_a = process.env.AZURE_ADDITIONALLY_ALLOWED_TENANTS) !== null && _a !== void 0 ? _a : "";
|
|
3874
|
-
return additionallyAllowedValues.split(";");
|
|
3875
|
-
}
|
|
3876
|
-
const credentialName$2 = "EnvironmentCredential";
|
|
3877
|
-
const logger$6 = credentialLogger(credentialName$2);
|
|
3878
|
-
/**
|
|
3879
|
-
* Enables authentication to Microsoft Entra ID using a client secret or certificate, or as a user
|
|
3880
|
-
* with a username and password.
|
|
3881
|
-
*/
|
|
3882
|
-
class EnvironmentCredential {
|
|
3883
|
-
/**
|
|
3884
|
-
* Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables.
|
|
3885
|
-
*
|
|
3886
|
-
* Required environment variables:
|
|
3887
|
-
* - `AZURE_TENANT_ID`: The Microsoft Entra tenant (directory) ID.
|
|
3888
|
-
* - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant.
|
|
3889
|
-
*
|
|
3890
|
-
* If setting the AZURE_TENANT_ID, then you can also set the additionally allowed tenants
|
|
3891
|
-
* - `AZURE_ADDITIONALLY_ALLOWED_TENANTS`: For multi-tenant applications, specifies additional tenants for which the credential may acquire tokens with a single semicolon delimited string. Use * to allow all tenants.
|
|
3892
|
-
*
|
|
3893
|
-
* Environment variables used for client credential authentication:
|
|
3894
|
-
* - `AZURE_CLIENT_SECRET`: A client secret that was generated for the App Registration.
|
|
3895
|
-
* - `AZURE_CLIENT_CERTIFICATE_PATH`: The path to a PEM certificate to use during the authentication, instead of the client secret.
|
|
3896
|
-
* - `AZURE_CLIENT_CERTIFICATE_PASSWORD`: (optional) password for the certificate file.
|
|
3897
|
-
*
|
|
3898
|
-
* Alternatively, users can provide environment variables for username and password authentication:
|
|
3899
|
-
* - `AZURE_USERNAME`: Username to authenticate with.
|
|
3900
|
-
* - `AZURE_PASSWORD`: Password to authenticate with.
|
|
3901
|
-
*
|
|
3902
|
-
* If the environment variables required to perform the authentication are missing, a {@link CredentialUnavailableError} will be thrown.
|
|
3903
|
-
* If the authentication fails, or if there's an unknown error, an {@link AuthenticationError} will be thrown.
|
|
3904
|
-
*
|
|
3905
|
-
* @param options - Options for configuring the client which makes the authentication request.
|
|
3906
|
-
*/
|
|
3907
|
-
constructor(options) {
|
|
3908
|
-
// Keep track of any missing environment variables for error details
|
|
3909
|
-
this._credential = undefined;
|
|
3910
|
-
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
|
|
3911
|
-
logger$6.info(`Found the following environment variables: ${assigned}`);
|
|
3912
|
-
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
3913
|
-
const additionallyAllowedTenantIds = getAdditionallyAllowedTenants();
|
|
3914
|
-
const newOptions = Object.assign(Object.assign({}, options), { additionallyAllowedTenantIds });
|
|
3915
|
-
if (tenantId) {
|
|
3916
|
-
checkTenantId(logger$6, tenantId);
|
|
3917
|
-
}
|
|
3918
|
-
if (tenantId && clientId && clientSecret) {
|
|
3919
|
-
logger$6.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
|
|
3920
|
-
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, newOptions);
|
|
3921
|
-
return;
|
|
3922
|
-
}
|
|
3923
|
-
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
|
|
3924
|
-
const certificatePassword = process.env.AZURE_CLIENT_CERTIFICATE_PASSWORD;
|
|
3925
|
-
if (tenantId && clientId && certificatePath) {
|
|
3926
|
-
logger$6.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
|
|
3927
|
-
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath, certificatePassword }, newOptions);
|
|
3928
|
-
return;
|
|
3929
|
-
}
|
|
3930
|
-
const username = process.env.AZURE_USERNAME;
|
|
3931
|
-
const password = process.env.AZURE_PASSWORD;
|
|
3932
|
-
if (tenantId && clientId && username && password) {
|
|
3933
|
-
logger$6.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
|
|
3934
|
-
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, newOptions);
|
|
4075
|
+
await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
|
|
4076
|
+
const response = (_c = (await ((_b = this.getApp("confidential", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _b === void 0 ? void 0 : _b.acquireTokenSilent(silentRequest)))) !== null && _c !== void 0 ? _c : (await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenSilent(silentRequest));
|
|
4077
|
+
return this.handleResult(scopes, response || undefined);
|
|
4078
|
+
}
|
|
4079
|
+
catch (err) {
|
|
4080
|
+
throw handleMsalError(scopes, err, options);
|
|
3935
4081
|
}
|
|
3936
4082
|
}
|
|
3937
4083
|
/**
|
|
3938
|
-
*
|
|
3939
|
-
*
|
|
3940
|
-
* @param scopes - The list of scopes for which the token will have access.
|
|
3941
|
-
* @param options - Optional parameters. See {@link GetTokenOptions}.
|
|
4084
|
+
* Wrapper around each MSAL flow get token operation: doGetToken.
|
|
4085
|
+
* If disableAutomaticAuthentication is sent through the constructor, it will prevent MSAL from requesting the user input.
|
|
3942
4086
|
*/
|
|
3943
4087
|
async getToken(scopes, options = {}) {
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
logger$6.getToken.info(formatError(scopes, authenticationError));
|
|
3957
|
-
throw authenticationError;
|
|
3958
|
-
}
|
|
4088
|
+
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
|
|
4089
|
+
this.tenantId;
|
|
4090
|
+
options.authority = getAuthority(tenantId, this.authorityHost);
|
|
4091
|
+
options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || randomUUID();
|
|
4092
|
+
await this.init(options);
|
|
4093
|
+
try {
|
|
4094
|
+
// MSAL now caches tokens based on their claims,
|
|
4095
|
+
// so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
|
|
4096
|
+
// This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
|
|
4097
|
+
const optionsClaims = options.claims;
|
|
4098
|
+
if (optionsClaims) {
|
|
4099
|
+
this.cachedClaims = optionsClaims;
|
|
3959
4100
|
}
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
}
|
|
3963
|
-
}
|
|
3964
|
-
|
|
3965
|
-
// Copyright (c) Microsoft Corporation.
|
|
3966
|
-
// Licensed under the MIT license.
|
|
3967
|
-
const logger$5 = credentialLogger("DefaultAzureCredential");
|
|
3968
|
-
/**
|
|
3969
|
-
* Creates a {@link ManagedIdentityCredential} from the provided options.
|
|
3970
|
-
* @param options - Options to configure the credential.
|
|
3971
|
-
*
|
|
3972
|
-
* @internal
|
|
3973
|
-
*/
|
|
3974
|
-
function createDefaultManagedIdentityCredential(options = {}) {
|
|
3975
|
-
var _a, _b, _c, _d;
|
|
3976
|
-
(_a = options.retryOptions) !== null && _a !== void 0 ? _a : (options.retryOptions = {
|
|
3977
|
-
maxRetries: 5,
|
|
3978
|
-
retryDelayInMs: 800,
|
|
3979
|
-
});
|
|
3980
|
-
const managedIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
|
|
3981
|
-
const workloadIdentityClientId = (_c = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _c !== void 0 ? _c : managedIdentityClientId;
|
|
3982
|
-
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
|
|
3983
|
-
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
3984
|
-
const tenantId = (_d = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _d !== void 0 ? _d : process.env.AZURE_TENANT_ID;
|
|
3985
|
-
if (managedResourceId) {
|
|
3986
|
-
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
|
|
3987
|
-
return new ManagedIdentityCredential(managedIdentityResourceIdOptions);
|
|
3988
|
-
}
|
|
3989
|
-
if (workloadFile && workloadIdentityClientId) {
|
|
3990
|
-
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId: tenantId });
|
|
3991
|
-
return new ManagedIdentityCredential(workloadIdentityClientId, workloadIdentityCredentialOptions);
|
|
3992
|
-
}
|
|
3993
|
-
if (managedIdentityClientId) {
|
|
3994
|
-
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
|
|
3995
|
-
return new ManagedIdentityCredential(managedIdentityClientOptions);
|
|
3996
|
-
}
|
|
3997
|
-
// We may be able to return a UnavailableCredential here, but that may be a breaking change
|
|
3998
|
-
return new ManagedIdentityCredential(options);
|
|
3999
|
-
}
|
|
4000
|
-
/**
|
|
4001
|
-
* Creates a {@link WorkloadIdentityCredential} from the provided options.
|
|
4002
|
-
* @param options - Options to configure the credential.
|
|
4003
|
-
*
|
|
4004
|
-
* @internal
|
|
4005
|
-
*/
|
|
4006
|
-
function createDefaultWorkloadIdentityCredential(options) {
|
|
4007
|
-
var _a, _b, _c;
|
|
4008
|
-
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
|
|
4009
|
-
const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
|
|
4010
|
-
const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
4011
|
-
const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
|
|
4012
|
-
if (workloadFile && workloadIdentityClientId) {
|
|
4013
|
-
const workloadIdentityCredentialOptions = Object.assign(Object.assign({}, options), { tenantId, clientId: workloadIdentityClientId, tokenFilePath: workloadFile });
|
|
4014
|
-
return new WorkloadIdentityCredential(workloadIdentityCredentialOptions);
|
|
4015
|
-
}
|
|
4016
|
-
if (tenantId) {
|
|
4017
|
-
const workloadIdentityClientTenantOptions = Object.assign(Object.assign({}, options), { tenantId });
|
|
4018
|
-
return new WorkloadIdentityCredential(workloadIdentityClientTenantOptions);
|
|
4019
|
-
}
|
|
4020
|
-
// We may be able to return a UnavailableCredential here, but that may be a breaking change
|
|
4021
|
-
return new WorkloadIdentityCredential(options);
|
|
4022
|
-
}
|
|
4023
|
-
/**
|
|
4024
|
-
* Creates a {@link AzureDeveloperCliCredential} from the provided options.
|
|
4025
|
-
* @param options - Options to configure the credential.
|
|
4026
|
-
*
|
|
4027
|
-
* @internal
|
|
4028
|
-
*/
|
|
4029
|
-
function createDefaultAzureDeveloperCliCredential(options = {}) {
|
|
4030
|
-
const processTimeoutInMs = options.processTimeoutInMs;
|
|
4031
|
-
return new AzureDeveloperCliCredential(Object.assign({ processTimeoutInMs }, options));
|
|
4032
|
-
}
|
|
4033
|
-
/**
|
|
4034
|
-
* Creates a {@link AzureCliCredential} from the provided options.
|
|
4035
|
-
* @param options - Options to configure the credential.
|
|
4036
|
-
*
|
|
4037
|
-
* @internal
|
|
4038
|
-
*/
|
|
4039
|
-
function createDefaultAzureCliCredential(options = {}) {
|
|
4040
|
-
const processTimeoutInMs = options.processTimeoutInMs;
|
|
4041
|
-
return new AzureCliCredential(Object.assign({ processTimeoutInMs }, options));
|
|
4042
|
-
}
|
|
4043
|
-
/**
|
|
4044
|
-
* Creates a {@link AzurePowerShellCredential} from the provided options.
|
|
4045
|
-
* @param options - Options to configure the credential.
|
|
4046
|
-
*
|
|
4047
|
-
* @internal
|
|
4048
|
-
*/
|
|
4049
|
-
function createDefaultAzurePowershellCredential(options = {}) {
|
|
4050
|
-
const processTimeoutInMs = options.processTimeoutInMs;
|
|
4051
|
-
return new AzurePowerShellCredential(Object.assign({ processTimeoutInMs }, options));
|
|
4052
|
-
}
|
|
4053
|
-
/**
|
|
4054
|
-
* Creates an {@link EnvironmentCredential} from the provided options.
|
|
4055
|
-
* @param options - Options to configure the credential.
|
|
4056
|
-
*
|
|
4057
|
-
* @internal
|
|
4058
|
-
*/
|
|
4059
|
-
function createEnvironmentCredential(options = {}) {
|
|
4060
|
-
return new EnvironmentCredential(options);
|
|
4061
|
-
}
|
|
4062
|
-
/**
|
|
4063
|
-
* A no-op credential that logs the reason it was skipped if getToken is called.
|
|
4064
|
-
* @internal
|
|
4065
|
-
*/
|
|
4066
|
-
class UnavailableDefaultCredential {
|
|
4067
|
-
constructor(credentialName, message) {
|
|
4068
|
-
this.credentialName = credentialName;
|
|
4069
|
-
this.credentialUnavailableErrorMessage = message;
|
|
4070
|
-
}
|
|
4071
|
-
getToken() {
|
|
4072
|
-
logger$5.getToken.info(`Skipping ${this.credentialName}, reason: ${this.credentialUnavailableErrorMessage}`);
|
|
4073
|
-
return Promise.resolve(null);
|
|
4074
|
-
}
|
|
4075
|
-
}
|
|
4076
|
-
/**
|
|
4077
|
-
* Provides a default {@link ChainedTokenCredential} configuration that should
|
|
4078
|
-
* work for most applications that use the Azure SDK.
|
|
4079
|
-
*/
|
|
4080
|
-
class DefaultAzureCredential extends ChainedTokenCredential {
|
|
4081
|
-
constructor(options) {
|
|
4082
|
-
const credentialFunctions = [
|
|
4083
|
-
createEnvironmentCredential,
|
|
4084
|
-
createDefaultWorkloadIdentityCredential,
|
|
4085
|
-
createDefaultManagedIdentityCredential,
|
|
4086
|
-
createDefaultAzureCliCredential,
|
|
4087
|
-
createDefaultAzurePowershellCredential,
|
|
4088
|
-
createDefaultAzureDeveloperCliCredential,
|
|
4089
|
-
];
|
|
4090
|
-
// DefaultCredential constructors should not throw, instead throwing on getToken() which is handled by ChainedTokenCredential.
|
|
4091
|
-
// When adding new credentials to the default chain, consider:
|
|
4092
|
-
// 1. Making the constructor parameters required and explicit
|
|
4093
|
-
// 2. Validating any required parameters in the factory function
|
|
4094
|
-
// 3. Returning a UnavailableDefaultCredential from the factory function if a credential is unavailable for any reason
|
|
4095
|
-
const credentials = credentialFunctions.map((createCredentialFn) => {
|
|
4096
|
-
try {
|
|
4097
|
-
return createCredentialFn(options);
|
|
4101
|
+
if (this.cachedClaims && !optionsClaims) {
|
|
4102
|
+
options.claims = this.cachedClaims;
|
|
4098
4103
|
}
|
|
4099
|
-
catch
|
|
4100
|
-
|
|
4101
|
-
|
|
4104
|
+
// We don't return the promise since we want to catch errors right here.
|
|
4105
|
+
return await this.getTokenSilent(scopes, options);
|
|
4106
|
+
}
|
|
4107
|
+
catch (err) {
|
|
4108
|
+
if (err.name !== "AuthenticationRequiredError") {
|
|
4109
|
+
throw err;
|
|
4102
4110
|
}
|
|
4103
|
-
|
|
4104
|
-
|
|
4111
|
+
if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
|
|
4112
|
+
throw new AuthenticationRequiredError({
|
|
4113
|
+
scopes,
|
|
4114
|
+
getTokenOptions: options,
|
|
4115
|
+
message: "Automatic authentication has been disabled. You may call the authentication() method.",
|
|
4116
|
+
});
|
|
4117
|
+
}
|
|
4118
|
+
this.logger.info(`Silent authentication failed, falling back to interactive method.`);
|
|
4119
|
+
return this.doGetToken(scopes, options);
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
4122
|
+
/**
|
|
4123
|
+
* Handles the MSAL authentication result.
|
|
4124
|
+
* If the result has an account, we update the local account reference.
|
|
4125
|
+
* If the token received is invalid, an error will be thrown depending on what's missing.
|
|
4126
|
+
*/
|
|
4127
|
+
handleResult(scopes, result, getTokenOptions) {
|
|
4128
|
+
if (result === null || result === void 0 ? void 0 : result.account) {
|
|
4129
|
+
this.account = msalToPublic(this.clientId, result.account);
|
|
4130
|
+
}
|
|
4131
|
+
ensureValidMsalToken(scopes, result, getTokenOptions);
|
|
4132
|
+
this.logger.getToken.info(formatSuccess(scopes));
|
|
4133
|
+
return {
|
|
4134
|
+
token: result.accessToken,
|
|
4135
|
+
expiresOnTimestamp: result.expiresOn.getTime(),
|
|
4136
|
+
};
|
|
4105
4137
|
}
|
|
4106
4138
|
}
|
|
4107
4139
|
|
|
@@ -4344,7 +4376,7 @@ class DeviceCodeCredential {
|
|
|
4344
4376
|
const clientId = (_a = options === null || options === void 0 ? void 0 : options.clientId) !== null && _a !== void 0 ? _a : DeveloperSignOnClientId;
|
|
4345
4377
|
const tenantId = resolveTenantId(logger$3, options === null || options === void 0 ? void 0 : options.tenantId, clientId);
|
|
4346
4378
|
this.userPromptCallback = (_b = options === null || options === void 0 ? void 0 : options.userPromptCallback) !== null && _b !== void 0 ? _b : defaultDeviceCodePromptCallback;
|
|
4347
|
-
this.msalClient = createMsalClient(clientId, tenantId, Object.assign(Object.assign({}, options), { tokenCredentialOptions: options || {} }));
|
|
4379
|
+
this.msalClient = createMsalClient(clientId, tenantId, Object.assign(Object.assign({}, options), { logger: logger$3, tokenCredentialOptions: options || {} }));
|
|
4348
4380
|
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
|
|
4349
4381
|
}
|
|
4350
4382
|
/**
|
|
@@ -4389,7 +4421,7 @@ class DeviceCodeCredential {
|
|
|
4389
4421
|
// Licensed under the MIT license.
|
|
4390
4422
|
const credentialName$1 = "AzurePipelinesCredential";
|
|
4391
4423
|
const logger$2 = credentialLogger(credentialName$1);
|
|
4392
|
-
const OIDC_API_VERSION = "7.1
|
|
4424
|
+
const OIDC_API_VERSION = "7.1";
|
|
4393
4425
|
/**
|
|
4394
4426
|
* This credential is designed to be used in Azure Pipelines with service connections
|
|
4395
4427
|
* as a setup for workload identity federation.
|
|
@@ -4399,23 +4431,23 @@ class AzurePipelinesCredential {
|
|
|
4399
4431
|
* AzurePipelinesCredential supports Federated Identity on Azure Pipelines through Service Connections.
|
|
4400
4432
|
* @param tenantId - tenantId associated with the service connection
|
|
4401
4433
|
* @param clientId - clientId associated with the service connection
|
|
4402
|
-
* @param serviceConnectionId -
|
|
4434
|
+
* @param serviceConnectionId - Unique ID for the service connection, as found in the querystring's resourceId key
|
|
4435
|
+
* @param systemAccessToken - The pipeline's <see href="https://learn.microsoft.com/azure/devops/pipelines/build/variables?view=azure-devops%26tabs=yaml#systemaccesstoken">System.AccessToken</see> value.
|
|
4403
4436
|
* @param options - The identity client options to use for authentication.
|
|
4404
4437
|
*/
|
|
4405
|
-
constructor(tenantId, clientId, serviceConnectionId, options) {
|
|
4406
|
-
if (!clientId || !tenantId || !serviceConnectionId) {
|
|
4407
|
-
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. tenantId, clientId, and
|
|
4438
|
+
constructor(tenantId, clientId, serviceConnectionId, systemAccessToken, options) {
|
|
4439
|
+
if (!clientId || !tenantId || !serviceConnectionId || !systemAccessToken) {
|
|
4440
|
+
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. tenantId, clientId, serviceConnectionId, and systemAccessToken are required parameters.`);
|
|
4408
4441
|
}
|
|
4409
4442
|
this.identityClient = new IdentityClient(options);
|
|
4410
4443
|
checkTenantId(logger$2, tenantId);
|
|
4411
|
-
logger$2.info(`Invoking AzurePipelinesCredential with tenant ID: ${tenantId},
|
|
4412
|
-
if (
|
|
4413
|
-
this
|
|
4414
|
-
const oidcRequestUrl = `${process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${process.env.SYSTEM_TEAMPROJECTID}/_apis/distributedtask/hubs/build/plans/${process.env.SYSTEM_PLANID}/jobs/${process.env.SYSTEM_JOBID}/oidctoken?api-version=${OIDC_API_VERSION}&serviceConnectionId=${serviceConnectionId}`;
|
|
4415
|
-
const systemAccessToken = `${process.env.SYSTEM_ACCESSTOKEN}`;
|
|
4416
|
-
logger$2.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${clientId} and service connection id: ${serviceConnectionId}`);
|
|
4417
|
-
this.clientAssertionCredential = new ClientAssertionCredential(tenantId, clientId, this.requestOidcToken.bind(this, oidcRequestUrl, systemAccessToken), options);
|
|
4444
|
+
logger$2.info(`Invoking AzurePipelinesCredential with tenant ID: ${tenantId}, client ID: ${clientId}, and service connection ID: ${serviceConnectionId}`);
|
|
4445
|
+
if (!process.env.SYSTEM_OIDCREQUESTURI) {
|
|
4446
|
+
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. Ensure that you're running this task in an Azure Pipeline, so that following missing system variable(s) can be defined- "SYSTEM_OIDCREQUESTURI"`);
|
|
4418
4447
|
}
|
|
4448
|
+
const oidcRequestUrl = `${process.env.SYSTEM_OIDCREQUESTURI}?api-version=${OIDC_API_VERSION}&serviceConnectionId=${serviceConnectionId}`;
|
|
4449
|
+
logger$2.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, client ID: ${clientId} and service connection ID: ${serviceConnectionId}`);
|
|
4450
|
+
this.clientAssertionCredential = new ClientAssertionCredential(tenantId, clientId, this.requestOidcToken.bind(this, oidcRequestUrl, systemAccessToken), options);
|
|
4419
4451
|
}
|
|
4420
4452
|
/**
|
|
4421
4453
|
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
@@ -4427,16 +4459,13 @@ class AzurePipelinesCredential {
|
|
|
4427
4459
|
*/
|
|
4428
4460
|
async getToken(scopes, options) {
|
|
4429
4461
|
if (!this.clientAssertionCredential) {
|
|
4430
|
-
const errorMessage = `${credentialName$1}: is unavailable. To use Federation Identity in Azure Pipelines,
|
|
4462
|
+
const errorMessage = `${credentialName$1}: is unavailable. To use Federation Identity in Azure Pipelines, the following parameters are required -
|
|
4431
4463
|
tenantId,
|
|
4432
4464
|
clientId,
|
|
4433
4465
|
serviceConnectionId,
|
|
4434
|
-
|
|
4435
|
-
"
|
|
4436
|
-
|
|
4437
|
-
"SYSTEM_JOBID" &&
|
|
4438
|
-
"SYSTEM_ACCESSTOKEN"
|
|
4439
|
-
See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/troubleshoot`;
|
|
4466
|
+
systemAccessToken,
|
|
4467
|
+
"SYSTEM_OIDCREQUESTURI".
|
|
4468
|
+
See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`;
|
|
4440
4469
|
logger$2.error(errorMessage);
|
|
4441
4470
|
throw new CredentialUnavailableError(errorMessage);
|
|
4442
4471
|
}
|
|
@@ -4464,92 +4493,26 @@ class AzurePipelinesCredential {
|
|
|
4464
4493
|
const text = response.bodyAsText;
|
|
4465
4494
|
if (!text) {
|
|
4466
4495
|
logger$2.error(`${credentialName$1}: Authenticated Failed. Received null token from OIDC request. Response status- ${response.status}. Complete response - ${JSON.stringify(response)}`);
|
|
4467
|
-
throw new
|
|
4468
|
-
}
|
|
4469
|
-
const result = JSON.parse(text);
|
|
4470
|
-
if (result === null || result === void 0 ? void 0 : result.oidcToken) {
|
|
4471
|
-
return result.oidcToken;
|
|
4472
|
-
}
|
|
4473
|
-
else {
|
|
4474
|
-
logger$2.error(`${credentialName$1}: Authentication Failed. oidcToken field not detected in the response. Response = ${JSON.stringify(result)}`);
|
|
4475
|
-
throw new CredentialUnavailableError(`${credentialName$1}: Authentication Failed. oidcToken field not detected in the response. Response = ${JSON.stringify(result)}`);
|
|
4476
|
-
}
|
|
4477
|
-
}
|
|
4478
|
-
/**
|
|
4479
|
-
* Ensures all system env vars are there to form the request uri for OIDC token
|
|
4480
|
-
* @returns void
|
|
4481
|
-
* @throws CredentialUnavailableError
|
|
4482
|
-
*/
|
|
4483
|
-
ensurePipelinesSystemVars() {
|
|
4484
|
-
if (process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI &&
|
|
4485
|
-
process.env.SYSTEM_TEAMPROJECTID &&
|
|
4486
|
-
process.env.SYSTEM_PLANID &&
|
|
4487
|
-
process.env.SYSTEM_JOBID &&
|
|
4488
|
-
process.env.SYSTEM_ACCESSTOKEN) {
|
|
4489
|
-
return;
|
|
4496
|
+
throw new AuthenticationError(response.status, `${credentialName$1}: Authenticated Failed. Received null token from OIDC request. Response status- ${response.status}. Complete response - ${JSON.stringify(response)}`);
|
|
4490
4497
|
}
|
|
4491
|
-
const missingEnvVars = [];
|
|
4492
|
-
let errorMessage = "";
|
|
4493
|
-
if (!process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) {
|
|
4494
|
-
missingEnvVars.push("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI");
|
|
4495
|
-
}
|
|
4496
|
-
if (!process.env.SYSTEM_TEAMPROJECTID)
|
|
4497
|
-
missingEnvVars.push("SYSTEM_TEAMPROJECTID");
|
|
4498
|
-
if (!process.env.SYSTEM_PLANID)
|
|
4499
|
-
missingEnvVars.push("SYSTEM_PLANID");
|
|
4500
|
-
if (!process.env.SYSTEM_JOBID)
|
|
4501
|
-
missingEnvVars.push("SYSTEM_JOBID");
|
|
4502
|
-
if (!process.env.SYSTEM_ACCESSTOKEN) {
|
|
4503
|
-
errorMessage +=
|
|
4504
|
-
"\nPlease ensure that the system access token is available in the SYSTEM_ACCESSTOKEN value; this is often most easily achieved by adding a block to the end of your pipeline yaml for the task with:\n env: \n- SYSTEM_ACCESSTOKEN: $(System.AccessToken)";
|
|
4505
|
-
missingEnvVars.push("SYSTEM_ACCESSTOKEN");
|
|
4506
|
-
}
|
|
4507
|
-
if (missingEnvVars.length > 0) {
|
|
4508
|
-
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. Ensure that you're running this task in an Azure Pipeline, so that following missing system variable(s) can be defined- ${missingEnvVars.join(", ")}.${errorMessage}`);
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
}
|
|
4512
|
-
|
|
4513
|
-
// Copyright (c) Microsoft Corporation.
|
|
4514
|
-
// Licensed under the MIT license.
|
|
4515
|
-
/**
|
|
4516
|
-
* This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`
|
|
4517
|
-
* to trigger the authentication flow, and then respond based on the values obtained from the redirect callback
|
|
4518
|
-
* @internal
|
|
4519
|
-
*/
|
|
4520
|
-
class MsalAuthorizationCode extends MsalNode {
|
|
4521
|
-
constructor(options) {
|
|
4522
|
-
super(options);
|
|
4523
|
-
this.logger = credentialLogger("Node.js MSAL Authorization Code");
|
|
4524
|
-
this.redirectUri = options.redirectUri;
|
|
4525
|
-
this.authorizationCode = options.authorizationCode;
|
|
4526
|
-
if (options.clientSecret) {
|
|
4527
|
-
this.msalConfig.auth.clientSecret = options.clientSecret;
|
|
4528
|
-
}
|
|
4529
|
-
}
|
|
4530
|
-
async getAuthCodeUrl(options) {
|
|
4531
|
-
await this.init();
|
|
4532
|
-
return this.getApp("confidentialFirst", options.enableCae).getAuthCodeUrl({
|
|
4533
|
-
scopes: options.scopes,
|
|
4534
|
-
redirectUri: options.redirectUri,
|
|
4535
|
-
});
|
|
4536
|
-
}
|
|
4537
|
-
async doGetToken(scopes, options) {
|
|
4538
4498
|
try {
|
|
4539
|
-
const result =
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4499
|
+
const result = JSON.parse(text);
|
|
4500
|
+
if (result === null || result === void 0 ? void 0 : result.oidcToken) {
|
|
4501
|
+
return result.oidcToken;
|
|
4502
|
+
}
|
|
4503
|
+
else {
|
|
4504
|
+
let errorMessage = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
|
4505
|
+
if (response.status !== 200) {
|
|
4506
|
+
errorMessage += `Response = ${JSON.stringify(result)}`;
|
|
4507
|
+
}
|
|
4508
|
+
logger$2.error(errorMessage);
|
|
4509
|
+
throw new AuthenticationError(response.status, errorMessage);
|
|
4510
|
+
}
|
|
4550
4511
|
}
|
|
4551
|
-
catch (
|
|
4552
|
-
|
|
4512
|
+
catch (e) {
|
|
4513
|
+
logger$2.error(e.message);
|
|
4514
|
+
logger$2.error(`${credentialName$1}: Authentication Failed. oidcToken field not detected in the response. Response = ${text}`);
|
|
4515
|
+
throw new AuthenticationError(response.status, `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response. Response = ${text}`);
|
|
4553
4516
|
}
|
|
4554
4517
|
}
|
|
4555
4518
|
}
|
|
@@ -4571,7 +4534,7 @@ class AuthorizationCodeCredential {
|
|
|
4571
4534
|
*/
|
|
4572
4535
|
constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
|
|
4573
4536
|
checkTenantId(logger$1, tenantId);
|
|
4574
|
-
|
|
4537
|
+
this.clientSecret = clientSecretOrAuthorizationCode;
|
|
4575
4538
|
if (typeof redirectUriOrOptions === "string") {
|
|
4576
4539
|
// the clientId+clientSecret constructor
|
|
4577
4540
|
this.authorizationCode = authorizationCodeOrRedirectUri;
|
|
@@ -4582,15 +4545,13 @@ class AuthorizationCodeCredential {
|
|
|
4582
4545
|
// clientId only
|
|
4583
4546
|
this.authorizationCode = clientSecretOrAuthorizationCode;
|
|
4584
4547
|
this.redirectUri = authorizationCodeOrRedirectUri;
|
|
4585
|
-
clientSecret = undefined;
|
|
4548
|
+
this.clientSecret = undefined;
|
|
4586
4549
|
options = redirectUriOrOptions;
|
|
4587
4550
|
}
|
|
4588
4551
|
// TODO: Validate tenant if provided
|
|
4589
4552
|
this.tenantId = tenantId;
|
|
4590
4553
|
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
|
4591
|
-
this.
|
|
4592
|
-
clientId,
|
|
4593
|
-
tenantId, tokenCredentialOptions: options || {}, logger: logger$1, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
|
|
4554
|
+
this.msalClient = createMsalClient(clientId, tenantId, Object.assign(Object.assign({}, options), { logger: logger$1, tokenCredentialOptions: options !== null && options !== void 0 ? options : {} }));
|
|
4594
4555
|
}
|
|
4595
4556
|
/**
|
|
4596
4557
|
* Authenticates with Microsoft Entra ID and returns an access token if successful.
|
|
@@ -4605,7 +4566,7 @@ class AuthorizationCodeCredential {
|
|
|
4605
4566
|
const tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds);
|
|
4606
4567
|
newOptions.tenantId = tenantId;
|
|
4607
4568
|
const arrayScopes = ensureScopes(scopes);
|
|
4608
|
-
return this.
|
|
4569
|
+
return this.msalClient.getTokenByAuthorizationCode(arrayScopes, this.redirectUri, this.authorizationCode, this.clientSecret, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
|
|
4609
4570
|
});
|
|
4610
4571
|
}
|
|
4611
4572
|
}
|