@azure/identity 2.0.2-alpha.20211105.2 → 2.0.2-alpha.20211203.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/CHANGELOG.md +2 -0
- package/dist/index.js +182 -102
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +1 -1
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureApplicationCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/azureApplicationCredential.js +1 -2
- package/dist-esm/src/credentials/azureApplicationCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.browser.js +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/credentialPersistenceOptions.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.js +5 -4
- package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/interactiveCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +18 -6
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +20 -6
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +13 -5
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +32 -17
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +16 -5
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +11 -12
- 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 +17 -5
- package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js +2 -10
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.js +3 -3
- package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/msal/browserFlows/msalAuthCode.js +1 -1
- package/dist-esm/src/msal/browserFlows/msalAuthCode.js.map +1 -1
- package/dist-esm/src/msal/browserFlows/{browserCommon.js → msalBrowserCommon.js} +1 -1
- package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js.map +1 -0
- package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientSecret.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClientSecret.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/{nodeCommon.js → msalNodeCommon.js} +2 -2
- package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js.map +1 -0
- package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js +16 -2
- package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js +1 -1
- package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js.map +1 -1
- package/dist-esm/src/plugins/consumer.js +1 -1
- package/dist-esm/src/plugins/consumer.js.map +1 -1
- package/dist-esm/src/tokenCredentialOptions.js +4 -0
- package/dist-esm/src/tokenCredentialOptions.js.map +1 -0
- package/package.json +2 -3
- package/types/identity.d.ts +4 -5
- package/dist-esm/src/msal/browserFlows/browserCommon.js.map +0 -1
- package/dist-esm/src/msal/nodeFlows/nodeCommon.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
### Features Added
|
|
6
6
|
|
|
7
|
+
- Improved the error message when `InteractiveBrowserCredential` is used with an unavailable port (such as when no `redirectUri` is provided, and the port `80` is busy) and when no browser is available.
|
|
8
|
+
|
|
7
9
|
### Breaking Changes
|
|
8
10
|
|
|
9
11
|
### Bugs Fixed
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
6
6
|
|
|
7
7
|
var msalNode = require('@azure/msal-node');
|
|
8
|
-
var coreClient = require('@azure/core-client');
|
|
9
8
|
var coreTracing = require('@azure/core-tracing');
|
|
9
|
+
var coreClient = require('@azure/core-client');
|
|
10
10
|
var coreUtil = require('@azure/core-util');
|
|
11
11
|
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
|
12
12
|
var abortController = require('@azure/abort-controller');
|
|
@@ -26,44 +26,6 @@ var http = _interopDefault(require('http'));
|
|
|
26
26
|
var open = _interopDefault(require('open'));
|
|
27
27
|
var stoppable = _interopDefault(require('stoppable'));
|
|
28
28
|
|
|
29
|
-
// Copyright (c) Microsoft Corporation.
|
|
30
|
-
// Licensed under the MIT license.
|
|
31
|
-
/**
|
|
32
|
-
* The default client ID for authentication
|
|
33
|
-
* @internal
|
|
34
|
-
*/
|
|
35
|
-
// TODO: temporary - this is the Azure CLI clientID - we'll replace it when
|
|
36
|
-
// Developer Sign On application is available
|
|
37
|
-
// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
|
|
38
|
-
const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
|
|
39
|
-
/**
|
|
40
|
-
* The default tenant for authentication
|
|
41
|
-
* @internal
|
|
42
|
-
*/
|
|
43
|
-
const DefaultTenantId = "common";
|
|
44
|
-
(function (AzureAuthorityHosts) {
|
|
45
|
-
/**
|
|
46
|
-
* China-based Azure Authority Host
|
|
47
|
-
*/
|
|
48
|
-
AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
|
|
49
|
-
/**
|
|
50
|
-
* Germany-based Azure Authority Host
|
|
51
|
-
*/
|
|
52
|
-
AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
|
|
53
|
-
/**
|
|
54
|
-
* US Government Azure Authority Host
|
|
55
|
-
*/
|
|
56
|
-
AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
|
|
57
|
-
/**
|
|
58
|
-
* Public Cloud Azure Authority Host
|
|
59
|
-
*/
|
|
60
|
-
AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
|
|
61
|
-
})(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
|
|
62
|
-
/**
|
|
63
|
-
* The default authority host.
|
|
64
|
-
*/
|
|
65
|
-
const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
|
|
66
|
-
|
|
67
29
|
// Copyright (c) Microsoft Corporation.
|
|
68
30
|
// Licensed under the MIT license.
|
|
69
31
|
function isErrorResponse(errorResponse) {
|
|
@@ -194,6 +156,44 @@ function getIdentityTokenEndpointSuffix(tenantId) {
|
|
|
194
156
|
}
|
|
195
157
|
}
|
|
196
158
|
|
|
159
|
+
// Copyright (c) Microsoft Corporation.
|
|
160
|
+
// Licensed under the MIT license.
|
|
161
|
+
/**
|
|
162
|
+
* The default client ID for authentication
|
|
163
|
+
* @internal
|
|
164
|
+
*/
|
|
165
|
+
// TODO: temporary - this is the Azure CLI clientID - we'll replace it when
|
|
166
|
+
// Developer Sign On application is available
|
|
167
|
+
// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
|
|
168
|
+
const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
|
|
169
|
+
/**
|
|
170
|
+
* The default tenant for authentication
|
|
171
|
+
* @internal
|
|
172
|
+
*/
|
|
173
|
+
const DefaultTenantId = "common";
|
|
174
|
+
(function (AzureAuthorityHosts) {
|
|
175
|
+
/**
|
|
176
|
+
* China-based Azure Authority Host
|
|
177
|
+
*/
|
|
178
|
+
AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
|
|
179
|
+
/**
|
|
180
|
+
* Germany-based Azure Authority Host
|
|
181
|
+
*/
|
|
182
|
+
AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
|
|
183
|
+
/**
|
|
184
|
+
* US Government Azure Authority Host
|
|
185
|
+
*/
|
|
186
|
+
AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
|
|
187
|
+
/**
|
|
188
|
+
* Public Cloud Azure Authority Host
|
|
189
|
+
*/
|
|
190
|
+
AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
|
|
191
|
+
})(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
|
|
192
|
+
/**
|
|
193
|
+
* The default authority host.
|
|
194
|
+
*/
|
|
195
|
+
const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
|
|
196
|
+
|
|
197
197
|
// Copyright (c) Microsoft Corporation.
|
|
198
198
|
/**
|
|
199
199
|
* Creates a span using the global tracer.
|
|
@@ -1496,7 +1496,7 @@ class AzureCliCredential {
|
|
|
1496
1496
|
ensureValidScope(scope, logger$3);
|
|
1497
1497
|
const resource = getScopeResource(scope);
|
|
1498
1498
|
let responseData = "";
|
|
1499
|
-
const { span } = createSpan(
|
|
1499
|
+
const { span } = createSpan(`${this.constructor.name}.getToken`, options);
|
|
1500
1500
|
try {
|
|
1501
1501
|
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId);
|
|
1502
1502
|
if (obj.stderr) {
|
|
@@ -2037,7 +2037,8 @@ const AllSupportedEnvironmentVariables = [
|
|
|
2037
2037
|
"AZURE_USERNAME",
|
|
2038
2038
|
"AZURE_PASSWORD"
|
|
2039
2039
|
];
|
|
2040
|
-
const
|
|
2040
|
+
const credentialName$1 = "EnvironmentCredential";
|
|
2041
|
+
const logger$8 = credentialLogger(credentialName$1);
|
|
2041
2042
|
/**
|
|
2042
2043
|
* Enables authentication to Azure Active Directory using client secret
|
|
2043
2044
|
* details configured in environment variables
|
|
@@ -2097,7 +2098,7 @@ class EnvironmentCredential {
|
|
|
2097
2098
|
* @param options - Optional parameters. See {@link GetTokenOptions}.
|
|
2098
2099
|
*/
|
|
2099
2100
|
async getToken(scopes, options = {}) {
|
|
2100
|
-
return trace(
|
|
2101
|
+
return trace(`${credentialName$1}.getToken`, options, async (newOptions) => {
|
|
2101
2102
|
if (this._credential) {
|
|
2102
2103
|
try {
|
|
2103
2104
|
const result = await this._credential.getToken(scopes, newOptions);
|
|
@@ -2106,7 +2107,7 @@ class EnvironmentCredential {
|
|
|
2106
2107
|
}
|
|
2107
2108
|
catch (err) {
|
|
2108
2109
|
const authenticationError = new AuthenticationError(400, {
|
|
2109
|
-
error:
|
|
2110
|
+
error: `${credentialName$1} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
|
|
2110
2111
|
error_description: err.message
|
|
2111
2112
|
.toString()
|
|
2112
2113
|
.split("More details:")
|
|
@@ -2116,7 +2117,7 @@ class EnvironmentCredential {
|
|
|
2116
2117
|
throw authenticationError;
|
|
2117
2118
|
}
|
|
2118
2119
|
}
|
|
2119
|
-
throw new CredentialUnavailableError(
|
|
2120
|
+
throw new CredentialUnavailableError(`${credentialName$1} is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`);
|
|
2120
2121
|
});
|
|
2121
2122
|
}
|
|
2122
2123
|
}
|
|
@@ -2132,7 +2133,8 @@ const azureFabricVersion = "2019-07-01-preview";
|
|
|
2132
2133
|
|
|
2133
2134
|
// Copyright (c) Microsoft Corporation.
|
|
2134
2135
|
/**
|
|
2135
|
-
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
|
|
2136
|
+
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
|
|
2137
|
+
* These are GET requests that require sending a `resource` parameter on the query.
|
|
2136
2138
|
* This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
|
|
2137
2139
|
* Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
|
|
2138
2140
|
*
|
|
@@ -2155,23 +2157,20 @@ function mapScopesToResource(scopes) {
|
|
|
2155
2157
|
}
|
|
2156
2158
|
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
|
|
2157
2159
|
}
|
|
2158
|
-
async function msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions = {}, agent) {
|
|
2159
|
-
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, requestOptions), { allowInsecureConnection: true }));
|
|
2160
|
-
if (agent) {
|
|
2161
|
-
request.agent = agent;
|
|
2162
|
-
}
|
|
2163
|
-
const tokenResponse = await identityClient.sendTokenRequest(request, expiresInParser);
|
|
2164
|
-
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2165
|
-
}
|
|
2166
2160
|
|
|
2167
2161
|
// Copyright (c) Microsoft Corporation.
|
|
2168
2162
|
const msiName = "ManagedIdentityCredential - AppServiceMSI 2017";
|
|
2169
2163
|
const logger$9 = credentialLogger(msiName);
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2164
|
+
/**
|
|
2165
|
+
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2166
|
+
*/
|
|
2167
|
+
function expiresOnParser(requestBody) {
|
|
2168
|
+
// App Service always returns string expires_on values.
|
|
2173
2169
|
return Date.parse(requestBody.expires_on);
|
|
2174
2170
|
}
|
|
2171
|
+
/**
|
|
2172
|
+
* Generates the options used on the request for an access token.
|
|
2173
|
+
*/
|
|
2175
2174
|
function prepareRequestOptions(scopes, clientId) {
|
|
2176
2175
|
const resource = mapScopesToResource(scopes);
|
|
2177
2176
|
if (!resource) {
|
|
@@ -2201,6 +2200,9 @@ function prepareRequestOptions(scopes, clientId) {
|
|
|
2201
2200
|
})
|
|
2202
2201
|
};
|
|
2203
2202
|
}
|
|
2203
|
+
/**
|
|
2204
|
+
* 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.
|
|
2205
|
+
*/
|
|
2204
2206
|
const appServiceMsi2017 = {
|
|
2205
2207
|
async isAvailable(scopes) {
|
|
2206
2208
|
const resource = mapScopesToResource(scopes);
|
|
@@ -2218,15 +2220,20 @@ const appServiceMsi2017 = {
|
|
|
2218
2220
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2219
2221
|
const { identityClient, scopes, clientId } = configuration;
|
|
2220
2222
|
logger$9.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
|
|
2221
|
-
|
|
2223
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId)), {
|
|
2224
|
+
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2225
|
+
allowInsecureConnection: true }));
|
|
2226
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
|
|
2227
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2222
2228
|
}
|
|
2223
2229
|
};
|
|
2224
2230
|
|
|
2225
2231
|
// Copyright (c) Microsoft Corporation.
|
|
2226
2232
|
const msiName$1 = "ManagedIdentityCredential - CloudShellMSI";
|
|
2227
2233
|
const logger$a = credentialLogger(msiName$1);
|
|
2228
|
-
|
|
2229
|
-
|
|
2234
|
+
/**
|
|
2235
|
+
* Generates the options used on the request for an access token.
|
|
2236
|
+
*/
|
|
2230
2237
|
function prepareRequestOptions$1(scopes, clientId) {
|
|
2231
2238
|
const resource = mapScopesToResource(scopes);
|
|
2232
2239
|
if (!resource) {
|
|
@@ -2254,6 +2261,9 @@ function prepareRequestOptions$1(scopes, clientId) {
|
|
|
2254
2261
|
})
|
|
2255
2262
|
};
|
|
2256
2263
|
}
|
|
2264
|
+
/**
|
|
2265
|
+
* Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
|
|
2266
|
+
*/
|
|
2257
2267
|
const cloudShellMsi = {
|
|
2258
2268
|
async isAvailable(scopes) {
|
|
2259
2269
|
const resource = mapScopesToResource(scopes);
|
|
@@ -2270,14 +2280,21 @@ const cloudShellMsi = {
|
|
|
2270
2280
|
async getToken(configuration, getTokenOptions = {}) {
|
|
2271
2281
|
const { identityClient, scopes, clientId } = configuration;
|
|
2272
2282
|
logger$a.info(`${msiName$1}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
|
|
2273
|
-
|
|
2283
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId)), {
|
|
2284
|
+
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2285
|
+
allowInsecureConnection: true }));
|
|
2286
|
+
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
2287
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2274
2288
|
}
|
|
2275
2289
|
};
|
|
2276
2290
|
|
|
2277
2291
|
// Copyright (c) Microsoft Corporation.
|
|
2278
2292
|
const msiName$2 = "ManagedIdentityCredential - IMDS";
|
|
2279
2293
|
const logger$b = credentialLogger(msiName$2);
|
|
2280
|
-
|
|
2294
|
+
/**
|
|
2295
|
+
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2296
|
+
*/
|
|
2297
|
+
function expiresOnParser$1(requestBody) {
|
|
2281
2298
|
if (requestBody.expires_on) {
|
|
2282
2299
|
// Use the expires_on timestamp if it's available
|
|
2283
2300
|
const expires = +requestBody.expires_on * 1000;
|
|
@@ -2291,6 +2308,9 @@ function expiresInParser$2(requestBody) {
|
|
|
2291
2308
|
return expires;
|
|
2292
2309
|
}
|
|
2293
2310
|
}
|
|
2311
|
+
/**
|
|
2312
|
+
* Generates the options used on the request for an access token.
|
|
2313
|
+
*/
|
|
2294
2314
|
function prepareRequestOptions$2(scopes, clientId, options) {
|
|
2295
2315
|
var _a;
|
|
2296
2316
|
const resource = mapScopesToResource(scopes);
|
|
@@ -2334,6 +2354,9 @@ const imdsMsiRetryConfig = {
|
|
|
2334
2354
|
startDelayInMs: 800,
|
|
2335
2355
|
intervalIncrement: 2
|
|
2336
2356
|
};
|
|
2357
|
+
/**
|
|
2358
|
+
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
|
|
2359
|
+
*/
|
|
2337
2360
|
const imdsMsi = {
|
|
2338
2361
|
async isAvailable(scopes, identityClient, clientId, getTokenOptions) {
|
|
2339
2362
|
var _a, _b;
|
|
@@ -2343,7 +2366,7 @@ const imdsMsi = {
|
|
|
2343
2366
|
return false;
|
|
2344
2367
|
}
|
|
2345
2368
|
const { span, updatedOptions: options } = createSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions);
|
|
2346
|
-
// if the
|
|
2369
|
+
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
|
|
2347
2370
|
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
|
|
2348
2371
|
return true;
|
|
2349
2372
|
}
|
|
@@ -2405,7 +2428,9 @@ const imdsMsi = {
|
|
|
2405
2428
|
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
|
|
2406
2429
|
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
|
|
2407
2430
|
try {
|
|
2408
|
-
|
|
2431
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId)), { allowInsecureConnection: true }));
|
|
2432
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$1);
|
|
2433
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2409
2434
|
}
|
|
2410
2435
|
catch (error) {
|
|
2411
2436
|
if (error.statusCode === 404) {
|
|
@@ -2423,8 +2448,9 @@ const imdsMsi = {
|
|
|
2423
2448
|
// Copyright (c) Microsoft Corporation.
|
|
2424
2449
|
const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
|
|
2425
2450
|
const logger$c = credentialLogger(msiName$3);
|
|
2426
|
-
|
|
2427
|
-
|
|
2451
|
+
/**
|
|
2452
|
+
* Generates the options used on the request for an access token.
|
|
2453
|
+
*/
|
|
2428
2454
|
function prepareRequestOptions$3(scopes) {
|
|
2429
2455
|
const resource = mapScopesToResource(scopes);
|
|
2430
2456
|
if (!resource) {
|
|
@@ -2449,7 +2475,10 @@ function prepareRequestOptions$3(scopes) {
|
|
|
2449
2475
|
})
|
|
2450
2476
|
});
|
|
2451
2477
|
}
|
|
2452
|
-
|
|
2478
|
+
/**
|
|
2479
|
+
* Retrieves the file contents at the given path using promises.
|
|
2480
|
+
* Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
|
|
2481
|
+
*/
|
|
2453
2482
|
function readFileAsync$1(path, options) {
|
|
2454
2483
|
return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
|
|
2455
2484
|
if (err) {
|
|
@@ -2458,6 +2487,9 @@ function readFileAsync$1(path, options) {
|
|
|
2458
2487
|
resolve(data);
|
|
2459
2488
|
}));
|
|
2460
2489
|
}
|
|
2490
|
+
/**
|
|
2491
|
+
* Does a request to the authentication provider that results in a file path.
|
|
2492
|
+
*/
|
|
2461
2493
|
async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
2462
2494
|
const response = await identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
|
|
2463
2495
|
if (response.status !== 401) {
|
|
@@ -2475,6 +2507,9 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
|
|
|
2475
2507
|
throw Error(`Invalid www-authenticate header format: ${authHeader}`);
|
|
2476
2508
|
}
|
|
2477
2509
|
}
|
|
2510
|
+
/**
|
|
2511
|
+
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
|
|
2512
|
+
*/
|
|
2478
2513
|
const arcMsi = {
|
|
2479
2514
|
async isAvailable(scopes) {
|
|
2480
2515
|
const resource = mapScopesToResource(scopes);
|
|
@@ -2502,7 +2537,11 @@ const arcMsi = {
|
|
|
2502
2537
|
}
|
|
2503
2538
|
const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
|
|
2504
2539
|
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
|
|
2505
|
-
|
|
2540
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
|
|
2541
|
+
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2542
|
+
allowInsecureConnection: true }));
|
|
2543
|
+
const tokenResponse = await identityClient.sendTokenRequest(request);
|
|
2544
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2506
2545
|
}
|
|
2507
2546
|
};
|
|
2508
2547
|
|
|
@@ -2510,10 +2549,16 @@ const arcMsi = {
|
|
|
2510
2549
|
const msiName$4 = "ManagedIdentityCredential - Token Exchange";
|
|
2511
2550
|
const logger$d = credentialLogger(msiName$4);
|
|
2512
2551
|
const readFileAsync$2 = util.promisify(fs__default.readFile);
|
|
2513
|
-
|
|
2552
|
+
/**
|
|
2553
|
+
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2554
|
+
*/
|
|
2555
|
+
function expiresOnParser$2(requestBody) {
|
|
2514
2556
|
// Parses a string representation of the seconds since epoch into a number value
|
|
2515
2557
|
return Number(requestBody.expires_on);
|
|
2516
2558
|
}
|
|
2559
|
+
/**
|
|
2560
|
+
* Generates the options used on the request for an access token.
|
|
2561
|
+
*/
|
|
2517
2562
|
function prepareRequestOptions$4(scopes, clientAssertion, clientId) {
|
|
2518
2563
|
var _a;
|
|
2519
2564
|
const bodyParams = {
|
|
@@ -2534,6 +2579,9 @@ function prepareRequestOptions$4(scopes, clientAssertion, clientId) {
|
|
|
2534
2579
|
})
|
|
2535
2580
|
};
|
|
2536
2581
|
}
|
|
2582
|
+
/**
|
|
2583
|
+
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
|
|
2584
|
+
*/
|
|
2537
2585
|
function tokenExchangeMsi() {
|
|
2538
2586
|
const azureFederatedTokenFilePath = process.env.AZURE_FEDERATED_TOKEN_FILE;
|
|
2539
2587
|
let azureFederatedTokenFileContent = undefined;
|
|
@@ -2576,18 +2624,38 @@ function tokenExchangeMsi() {
|
|
|
2576
2624
|
catch (err) {
|
|
2577
2625
|
throw new Error(`${msiName$4}: Failed to read ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
|
|
2578
2626
|
}
|
|
2579
|
-
|
|
2627
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID)), {
|
|
2628
|
+
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
|
|
2629
|
+
allowInsecureConnection: true }));
|
|
2630
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$2);
|
|
2631
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2580
2632
|
}
|
|
2581
2633
|
};
|
|
2582
2634
|
}
|
|
2583
2635
|
|
|
2584
2636
|
// Copyright (c) Microsoft Corporation.
|
|
2637
|
+
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
|
|
2638
|
+
//
|
|
2639
|
+
// FROM node:12
|
|
2640
|
+
// RUN wget https://host.any/path/bash.sh
|
|
2641
|
+
// CMD ["bash", "bash.sh"]
|
|
2642
|
+
//
|
|
2643
|
+
// Where the bash script contains:
|
|
2644
|
+
//
|
|
2645
|
+
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
2646
|
+
//
|
|
2585
2647
|
const msiName$5 = "ManagedIdentityCredential - Fabric MSI";
|
|
2586
2648
|
const logger$e = credentialLogger(msiName$5);
|
|
2587
|
-
|
|
2588
|
-
|
|
2649
|
+
/**
|
|
2650
|
+
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
|
|
2651
|
+
*/
|
|
2652
|
+
function expiresOnParser$3(requestBody) {
|
|
2653
|
+
// Parses a string representation of the milliseconds since epoch into a number value
|
|
2589
2654
|
return Number(requestBody.expires_on);
|
|
2590
2655
|
}
|
|
2656
|
+
/**
|
|
2657
|
+
* Generates the options used on the request for an access token.
|
|
2658
|
+
*/
|
|
2591
2659
|
function prepareRequestOptions$5(scopes, clientId) {
|
|
2592
2660
|
const resource = mapScopesToResource(scopes);
|
|
2593
2661
|
if (!resource) {
|
|
@@ -2613,20 +2681,13 @@ function prepareRequestOptions$5(scopes, clientId) {
|
|
|
2613
2681
|
method: "GET",
|
|
2614
2682
|
headers: coreRestPipeline.createHttpHeaders({
|
|
2615
2683
|
Accept: "application/json",
|
|
2616
|
-
|
|
2684
|
+
secret: process.env.IDENTITY_HEADER
|
|
2617
2685
|
})
|
|
2618
2686
|
};
|
|
2619
2687
|
}
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
// RUN wget https://host.any/path/bash.sh
|
|
2624
|
-
// CMD ["bash", "bash.sh"]
|
|
2625
|
-
//
|
|
2626
|
-
// Where the bash script contains:
|
|
2627
|
-
//
|
|
2628
|
-
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
|
|
2629
|
-
//
|
|
2688
|
+
/**
|
|
2689
|
+
* 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.
|
|
2690
|
+
*/
|
|
2630
2691
|
const fabricMsi = {
|
|
2631
2692
|
async isAvailable(scopes) {
|
|
2632
2693
|
const resource = mapScopesToResource(scopes);
|
|
@@ -2650,23 +2711,28 @@ const fabricMsi = {
|
|
|
2650
2711
|
"IDENTITY_HEADER=[REDACTED] and",
|
|
2651
2712
|
"IDENTITY_SERVER_THUMBPRINT=[REDACTED]."
|
|
2652
2713
|
].join(" "));
|
|
2653
|
-
|
|
2714
|
+
const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)
|
|
2715
|
+
// The service fabric MSI endpoint will be HTTPS (however, the certificate will be self-signed).
|
|
2716
|
+
// allowInsecureConnection: true
|
|
2717
|
+
));
|
|
2718
|
+
request.agent = new https.Agent({
|
|
2654
2719
|
// This is necessary because Service Fabric provides a self-signed certificate.
|
|
2655
2720
|
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
|
|
2656
2721
|
rejectUnauthorized: false
|
|
2657
|
-
})
|
|
2722
|
+
});
|
|
2723
|
+
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$3);
|
|
2724
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
2658
2725
|
}
|
|
2659
2726
|
};
|
|
2660
2727
|
|
|
2661
2728
|
// Copyright (c) Microsoft Corporation.
|
|
2662
2729
|
const logger$f = credentialLogger("ManagedIdentityCredential");
|
|
2663
2730
|
/**
|
|
2664
|
-
* Attempts authentication using a managed identity
|
|
2665
|
-
*
|
|
2666
|
-
*
|
|
2731
|
+
* Attempts authentication using a managed identity available at the deployment environment.
|
|
2732
|
+
* This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
|
|
2733
|
+
* Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.
|
|
2667
2734
|
*
|
|
2668
2735
|
* More information about configuring managed identities can be found here:
|
|
2669
|
-
*
|
|
2670
2736
|
* https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
|
|
2671
2737
|
*/
|
|
2672
2738
|
class ManagedIdentityCredential {
|
|
@@ -2697,10 +2763,10 @@ class ManagedIdentityCredential {
|
|
|
2697
2763
|
return msi;
|
|
2698
2764
|
}
|
|
2699
2765
|
}
|
|
2700
|
-
throw new CredentialUnavailableError(
|
|
2766
|
+
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
|
|
2701
2767
|
}
|
|
2702
2768
|
async authenticateManagedIdentity(scopes, clientId, getTokenOptions) {
|
|
2703
|
-
const { span, updatedOptions } = createSpan(
|
|
2769
|
+
const { span, updatedOptions } = createSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
|
|
2704
2770
|
try {
|
|
2705
2771
|
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
|
|
2706
2772
|
const availableMSI = await this.cachedAvailableMSI(scopes, clientId, updatedOptions);
|
|
@@ -2732,7 +2798,7 @@ class ManagedIdentityCredential {
|
|
|
2732
2798
|
*/
|
|
2733
2799
|
async getToken(scopes, options) {
|
|
2734
2800
|
let result = null;
|
|
2735
|
-
const { span, updatedOptions } = createSpan(
|
|
2801
|
+
const { span, updatedOptions } = createSpan(`${ManagedIdentityCredential.name}.getToken`, options);
|
|
2736
2802
|
try {
|
|
2737
2803
|
// isEndpointAvailable can be true, false, or null,
|
|
2738
2804
|
// If it's null, it means we don't yet know whether
|
|
@@ -2783,30 +2849,30 @@ class ManagedIdentityCredential {
|
|
|
2783
2849
|
// If either the network is unreachable,
|
|
2784
2850
|
// we can safely assume the credential is unavailable.
|
|
2785
2851
|
if (err.code === "ENETUNREACH") {
|
|
2786
|
-
const error = new CredentialUnavailableError(
|
|
2852
|
+
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
|
|
2787
2853
|
logger$f.getToken.info(formatError(scopes, error));
|
|
2788
2854
|
throw error;
|
|
2789
2855
|
}
|
|
2790
2856
|
// If either the host was unreachable,
|
|
2791
2857
|
// we can safely assume the credential is unavailable.
|
|
2792
2858
|
if (err.code === "EHOSTUNREACH") {
|
|
2793
|
-
const error = new CredentialUnavailableError(
|
|
2859
|
+
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
|
|
2794
2860
|
logger$f.getToken.info(formatError(scopes, error));
|
|
2795
2861
|
throw error;
|
|
2796
2862
|
}
|
|
2797
2863
|
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
|
2798
2864
|
// and it means that the endpoint is working, but that no identity is available.
|
|
2799
2865
|
if (err.statusCode === 400) {
|
|
2800
|
-
throw new CredentialUnavailableError(
|
|
2866
|
+
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
|
|
2801
2867
|
}
|
|
2802
2868
|
// If the error has no status code, we can assume there was no available identity.
|
|
2803
2869
|
// This will throw silently during any ChainedTokenCredential.
|
|
2804
2870
|
if (err.statusCode === undefined) {
|
|
2805
|
-
throw new CredentialUnavailableError(
|
|
2871
|
+
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Authentication failed. Message ${err.message}`);
|
|
2806
2872
|
}
|
|
2807
2873
|
// Any other error should break the chain.
|
|
2808
2874
|
throw new AuthenticationError(err.statusCode, {
|
|
2809
|
-
error:
|
|
2875
|
+
error: `${ManagedIdentityCredential.name} authentication failed.`,
|
|
2810
2876
|
error_description: err.message
|
|
2811
2877
|
});
|
|
2812
2878
|
}
|
|
@@ -2983,6 +3049,20 @@ class MsalOpenBrowser extends MsalNode {
|
|
|
2983
3049
|
}
|
|
2984
3050
|
}
|
|
2985
3051
|
app.on("connection", (socket) => socketToDestroy.push(socket));
|
|
3052
|
+
app.on("error", (err) => {
|
|
3053
|
+
cleanup();
|
|
3054
|
+
const code = err.code;
|
|
3055
|
+
if (code === "EACCES" || code === "EADDRINUSE") {
|
|
3056
|
+
reject(new CredentialUnavailableError([
|
|
3057
|
+
`InteractiveBrowserCredential: Access denied to port ${this.port}.`,
|
|
3058
|
+
`Try sending a redirect URI with a different port, as follows:`,
|
|
3059
|
+
'`new InteractiveBrowserCredential({ redirectUri: "http://localhost:1337" })`'
|
|
3060
|
+
].join(" ")));
|
|
3061
|
+
}
|
|
3062
|
+
else {
|
|
3063
|
+
reject(new CredentialUnavailableError(`InteractiveBrowserCredential: Failed to start the necessary web server. Error: ${err.message}`));
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
2986
3066
|
app.on("listening", () => {
|
|
2987
3067
|
const openPromise = this.openAuthCodeUrl(scopes, options);
|
|
2988
3068
|
const abortSignal = options === null || options === void 0 ? void 0 : options.abortSignal;
|
|
@@ -3019,7 +3099,7 @@ class MsalOpenBrowser extends MsalNode {
|
|
|
3019
3099
|
await interactiveBrowserMockable.open(response, { wait: true });
|
|
3020
3100
|
}
|
|
3021
3101
|
catch (e) {
|
|
3022
|
-
throw new CredentialUnavailableError(`Could not open a browser window. Error: ${e.message}`);
|
|
3102
|
+
throw new CredentialUnavailableError(`InteractiveBrowserCredential: Could not open a browser window. Error: ${e.message}`);
|
|
3023
3103
|
}
|
|
3024
3104
|
}
|
|
3025
3105
|
}
|
|
@@ -3262,7 +3342,7 @@ class AuthorizationCodeCredential {
|
|
|
3262
3342
|
// the clientId+clientSecret constructor
|
|
3263
3343
|
this.authorizationCode = authorizationCodeOrRedirectUri;
|
|
3264
3344
|
this.redirectUri = redirectUriOrOptions;
|
|
3265
|
-
// options
|
|
3345
|
+
// in this case, options are good as they come
|
|
3266
3346
|
}
|
|
3267
3347
|
else {
|
|
3268
3348
|
// clientId only
|
|
@@ -3344,8 +3424,8 @@ class MsalOnBehalfOf extends MsalNode {
|
|
|
3344
3424
|
}
|
|
3345
3425
|
|
|
3346
3426
|
// Copyright (c) Microsoft Corporation.
|
|
3347
|
-
const credentialName$
|
|
3348
|
-
const logger$j = credentialLogger(credentialName$
|
|
3427
|
+
const credentialName$2 = "OnBehalfOfCredential";
|
|
3428
|
+
const logger$j = credentialLogger(credentialName$2);
|
|
3349
3429
|
/**
|
|
3350
3430
|
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
|
|
3351
3431
|
*/
|
|
@@ -3377,7 +3457,7 @@ class OnBehalfOfCredential {
|
|
|
3377
3457
|
const { certificatePath } = options;
|
|
3378
3458
|
const { tenantId, clientId, userAssertionToken } = options;
|
|
3379
3459
|
if (!tenantId || !clientId || !(clientSecret || certificatePath) || !userAssertionToken) {
|
|
3380
|
-
throw new Error(`${credentialName$
|
|
3460
|
+
throw new Error(`${credentialName$2}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`);
|
|
3381
3461
|
}
|
|
3382
3462
|
this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger: logger$j, tokenCredentialOptions: this.options }));
|
|
3383
3463
|
}
|
|
@@ -3389,7 +3469,7 @@ class OnBehalfOfCredential {
|
|
|
3389
3469
|
* @param options - The options used to configure the underlying network requests.
|
|
3390
3470
|
*/
|
|
3391
3471
|
async getToken(scopes, options = {}) {
|
|
3392
|
-
return trace(`${credentialName$
|
|
3472
|
+
return trace(`${credentialName$2}.getToken`, options, async (newOptions) => {
|
|
3393
3473
|
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
3394
3474
|
return this.msalFlow.getToken(arrayScopes, newOptions);
|
|
3395
3475
|
});
|