@azure/identity 4.5.0-beta.3 → 4.5.1-alpha.20241021.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +28 -33
- package/dist/index.js +118 -28
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/identityClient.js +1 -0
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/constants.js +1 -1
- package/dist-esm/src/constants.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +18 -2
- 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/azureDeveloperCliCredential.js +1 -0
- package/dist-esm/src/credentials/azureDeveloperCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/azurePipelinesCredential.js +15 -4
- package/dist-esm/src/credentials/azurePipelinesCredential.js.map +1 -1
- package/dist-esm/src/credentials/azurePowerShellCredential.js +1 -0
- package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
- package/dist-esm/src/credentials/chainedTokenCredential.js +11 -3
- package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/src/credentials/credentialPersistenceOptions.js.map +1 -1
- package/dist-esm/src/credentials/defaultAzureCredential.js +15 -2
- package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +6 -4
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/legacyMsiProvider.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/legacyMsiProvider.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/msalMsiProvider.js +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/msalMsiProvider.js.map +1 -1
- package/dist-esm/src/credentials/onBehalfOfCredential.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/msalBrowserCommon.js +1 -0
- package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js.map +1 -1
- package/dist-esm/src/msal/nodeFlows/msalClient.js +25 -0
- package/dist-esm/src/msal/nodeFlows/msalClient.js.map +1 -1
- package/dist-esm/src/msal/utils.js +2 -1
- package/dist-esm/src/msal/utils.js.map +1 -1
- package/dist-esm/src/plugins/consumer.js +6 -8
- package/dist-esm/src/plugins/consumer.js.map +1 -1
- package/dist-esm/src/tokenProvider.js +3 -3
- package/dist-esm/src/tokenProvider.js.map +1 -1
- package/dist-esm/src/util/subscriptionUtils.js +14 -0
- package/dist-esm/src/util/subscriptionUtils.js.map +1 -0
- package/package.json +19 -18
- package/types/identity.d.ts +80 -99
package/README.md
CHANGED
@@ -47,7 +47,12 @@ Most of the credential types offered by `@azure/identity` use the [Microsoft Aut
|
|
47
47
|
|
48
48
|
The `@azure/identity` credential types are implementations of [@azure/core-auth](https://www.npmjs.com/package/@azure/core-auth)'s `TokenCredential` class. In principle, any object with a `getToken` method that satisfies `getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken | null>` works as a `TokenCredential`. This means developers can write their own credential types to support authentication cases not covered by `@azure/identity`. To learn more, see [Custom Credentials](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#custom-credentials).
|
49
49
|
|
50
|
-
Though our credential types support many advanced
|
50
|
+
Though our credential types support many advanced scenarios, developers may want to use [Microsoft Authentication Library for JavaScript (MSAL.js)](https://github.com/AzureAD/microsoft-authentication-library-for-js) directly instead. Consider using MSAL.js in the following scenarios:
|
51
|
+
|
52
|
+
- Developers who want full control of the authentication protocol and its configuration.
|
53
|
+
- Our credential types are designed to be used with Azure SDK clients with intelligent caching and token refreshing handled at the core HTTP layer. If you find yourself having to use `getToken` directly, you may benefit from using MSAL.js for more control over the authentication flow and token caching.
|
54
|
+
|
55
|
+
You can read more through the following links:
|
51
56
|
|
52
57
|
- We portray some advanced use cases of `@azure/identity` on the [Azure Identity Examples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md) page.
|
53
58
|
- There, we specifically have an [Advanced Examples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#advanced-examples) section.
|
@@ -117,20 +122,7 @@ See [Credential Classes](#credential-classes).
|
|
117
122
|
|
118
123
|
### DefaultAzureCredential
|
119
124
|
|
120
|
-
`DefaultAzureCredential`
|
121
|
-
|
122
|
-
> Note: `DefaultAzureCredential` is intended to simplify getting started with the SDK by handling common scenarios with reasonable default behaviors. Developers who want more control or whose scenario isn't served by the default settings should use other credential types.
|
123
|
-
|
124
|
-
If used from Node.js, `DefaultAzureCredential` attempts to authenticate via the following mechanisms in order:
|
125
|
-
|
126
|
-
![DefaultAzureCredential authentication flow][defaultauthflow_image]
|
127
|
-
|
128
|
-
1. **Environment** - `DefaultAzureCredential` reads account information specified via [environment variables](#environment-variables) and uses it to authenticate.
|
129
|
-
1. **Workload Identity** - If the application is deployed to Azure Kubernetes Service with Managed Identity enabled, `DefaultAzureCredential` authenticates with it.
|
130
|
-
1. **Managed Identity** - If the application is deployed to an Azure host with Managed Identity enabled, `DefaultAzureCredential` authenticates with that account.
|
131
|
-
1. **Azure CLI** - If the developer authenticated an account via the Azure CLI `az login` command, `DefaultAzureCredential` authenticates with that account.
|
132
|
-
1. **Azure PowerShell** - If the developer authenticated using the Azure PowerShell module `Connect-AzAccount` command, `DefaultAzureCredential` authenticates with that account.
|
133
|
-
1. **Azure Developer CLI** - If the developer authenticated an account via the Azure Developer CLI `azd auth login` command, `DefaultAzureCredential` authenticates with that account.
|
125
|
+
`DefaultAzureCredential` simplifies authentication while developing apps that deploy to Azure by combining credentials used in Azure hosting environments with credentials used in local development. For more information, see [DefaultAzureCredential overview](https://aka.ms/azsdk/js/identity/credential-chains#use-defaultazurecredential-for-flexibility).
|
134
126
|
|
135
127
|
#### Continuation policy
|
136
128
|
|
@@ -157,19 +149,14 @@ You can find more examples of using various credentials in [Azure Identity Examp
|
|
157
149
|
|
158
150
|
This example demonstrates authenticating the `KeyClient` from the [@azure/keyvault-keys](https://www.npmjs.com/package/@azure/keyvault-keys) client library using `DefaultAzureCredential`.
|
159
151
|
|
160
|
-
```
|
161
|
-
// The default credential first checks environment variables for configuration as described above.
|
162
|
-
// If environment configuration is incomplete, it will try managed identity.
|
163
|
-
|
164
|
-
// Azure Key Vault service to use
|
165
|
-
import { KeyClient } from "@azure/keyvault-keys";
|
166
|
-
|
167
|
-
// Azure authentication library to access Azure Key Vault
|
152
|
+
```ts snippet:defaultazurecredential_authenticate
|
168
153
|
import { DefaultAzureCredential } from "@azure/identity";
|
154
|
+
import { KeyClient } from "@azure/keyvault-keys";
|
169
155
|
|
156
|
+
// Configure vault URL
|
157
|
+
const vaultUrl = "https://<your-unique-keyvault-name>.vault.azure.net";
|
170
158
|
// Azure SDK clients accept the credential as a parameter
|
171
159
|
const credential = new DefaultAzureCredential();
|
172
|
-
|
173
160
|
// Create authenticated client
|
174
161
|
const client = new KeyClient(vaultUrl, credential);
|
175
162
|
```
|
@@ -182,17 +169,23 @@ A relatively common scenario involves authenticating using a user-assigned manag
|
|
182
169
|
|
183
170
|
While `DefaultAzureCredential` is generally the quickest way to get started developing applications for Azure, more advanced users may want to customize the credentials considered when authenticating. The `ChainedTokenCredential` enables users to combine multiple credential instances to define a customized chain of credentials. This example demonstrates creating a `ChainedTokenCredential` that attempts to authenticate using two differently configured instances of `ClientSecretCredential`, to then authenticate the `KeyClient` from the [@azure/keyvault-keys](https://www.npmjs.com/package/@azure/keyvault-keys):
|
184
171
|
|
185
|
-
```
|
172
|
+
```ts snippet:chaintedtokencredential_authenticate
|
186
173
|
import { ClientSecretCredential, ChainedTokenCredential } from "@azure/identity";
|
174
|
+
import { KeyClient } from "@azure/keyvault-keys";
|
187
175
|
|
176
|
+
// Configure variables
|
177
|
+
const vaultUrl = "https://<your-unique-keyvault-name>.vault.azure.net";
|
178
|
+
const tenantId = "<tenant-id>";
|
179
|
+
const clientId = "<client-id>";
|
180
|
+
const clientSecret = "<client-secret>";
|
181
|
+
const anotherClientId = "<another-client-id>";
|
182
|
+
const anotherSecret = "<another-client-secret>";
|
188
183
|
// When an access token is requested, the chain will try each
|
189
184
|
// credential in order, stopping when one provides a token
|
190
185
|
const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
|
191
186
|
const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
|
192
187
|
const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
|
193
|
-
|
194
188
|
// The chain can be used anywhere a credential is required
|
195
|
-
import { KeyClient } from "@azure/keyvault-keys";
|
196
189
|
const client = new KeyClient(vaultUrl, credentialChain);
|
197
190
|
```
|
198
191
|
|
@@ -214,15 +207,16 @@ For examples of how to use managed identity for authentication, see [the example
|
|
214
207
|
|
215
208
|
Credentials default to authenticating to the Microsoft Entra endpoint for Azure Public Cloud. To access resources in other clouds, such as Azure Government or a private cloud, configure credentials with the `authorityHost` argument in the constructor. The [`AzureAuthorityHosts`][authority_hosts] enum defines authorities for well-known clouds. For the US Government cloud, you could instantiate a credential this way:
|
216
209
|
|
217
|
-
```
|
218
|
-
import {
|
210
|
+
```ts snippet:cloudconfiguration_authenticate
|
211
|
+
import { ClientSecretCredential, AzureAuthorityHosts } from "@azure/identity";
|
212
|
+
|
219
213
|
const credential = new ClientSecretCredential(
|
220
214
|
"<YOUR_TENANT_ID>",
|
221
215
|
"<YOUR_CLIENT_ID>",
|
222
216
|
"<YOUR_CLIENT_SECRET>",
|
223
217
|
{
|
224
218
|
authorityHost: AzureAuthorityHosts.AzureGovernment,
|
225
|
-
}
|
219
|
+
},
|
226
220
|
);
|
227
221
|
```
|
228
222
|
|
@@ -234,15 +228,16 @@ AZURE_AUTHORITY_HOST=https://login.partner.microsoftonline.cn
|
|
234
228
|
|
235
229
|
The `AzureAuthorityHosts` enum defines authorities for well-known clouds for your convenience; however, if the authority for your cloud isn't listed in `AzureAuthorityHosts`, you may pass any valid authority URL as a string argument. For example:
|
236
230
|
|
237
|
-
```
|
238
|
-
import {
|
231
|
+
```ts snippet:cloudconfiguration_authorityhost
|
232
|
+
import { ClientSecretCredential } from "@azure/identity";
|
233
|
+
|
239
234
|
const credential = new ClientSecretCredential(
|
240
235
|
"<YOUR_TENANT_ID>",
|
241
236
|
"<YOUR_CLIENT_ID>",
|
242
237
|
"<YOUR_CLIENT_SECRET>",
|
243
238
|
{
|
244
239
|
authorityHost: "https://login.partner.microsoftonline.cn",
|
245
|
-
}
|
240
|
+
},
|
246
241
|
);
|
247
242
|
```
|
248
243
|
|
package/dist/index.js
CHANGED
@@ -44,7 +44,7 @@ var child_process__namespace = /*#__PURE__*/_interopNamespaceDefault(child_proce
|
|
44
44
|
/**
|
45
45
|
* Current version of the `@azure/identity` package.
|
46
46
|
*/
|
47
|
-
const SDK_VERSION = `4.5.
|
47
|
+
const SDK_VERSION = `4.5.1`;
|
48
48
|
/**
|
49
49
|
* The default client ID for authentication
|
50
50
|
* @internal
|
@@ -640,6 +640,7 @@ class IdentityClient extends coreClient.ServiceClient {
|
|
640
640
|
token: parsedBody.access_token,
|
641
641
|
expiresOnTimestamp: parseExpirationTimestamp(parsedBody),
|
642
642
|
refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),
|
643
|
+
tokenType: "Bearer",
|
643
644
|
},
|
644
645
|
refreshToken: parsedBody.refresh_token,
|
645
646
|
};
|
@@ -1017,18 +1018,16 @@ const pluginContext = {
|
|
1017
1018
|
*
|
1018
1019
|
* Example:
|
1019
1020
|
*
|
1020
|
-
* ```
|
1021
|
-
* import {
|
1021
|
+
* ```ts snippet:consumer_example
|
1022
|
+
* import { useIdentityPlugin, DeviceCodeCredential } from "@azure/identity";
|
1022
1023
|
*
|
1023
|
-
* import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
|
1024
1024
|
* useIdentityPlugin(cachePersistencePlugin);
|
1025
|
-
*
|
1026
|
-
* // The plugin has the capability to extend `DefaultAzureCredential` and to
|
1025
|
+
* // The plugin has the capability to extend `DeviceCodeCredential` and to
|
1027
1026
|
* // add middleware to the underlying credentials, such as persistence.
|
1028
|
-
* const credential = new
|
1027
|
+
* const credential = new DeviceCodeCredential({
|
1029
1028
|
* tokenCachePersistenceOptions: {
|
1030
|
-
* enabled: true
|
1031
|
-
* }
|
1029
|
+
* enabled: true,
|
1030
|
+
* },
|
1032
1031
|
* });
|
1033
1032
|
* ```
|
1034
1033
|
*
|
@@ -1184,7 +1183,8 @@ function handleMsalError(scopes, error, getTokenOptions) {
|
|
1184
1183
|
}
|
1185
1184
|
if (error.name === "ClientConfigurationError" ||
|
1186
1185
|
error.name === "BrowserConfigurationAuthError" ||
|
1187
|
-
error.name === "AbortError"
|
1186
|
+
error.name === "AbortError" ||
|
1187
|
+
error.name === "AuthenticationError") {
|
1188
1188
|
return error;
|
1189
1189
|
}
|
1190
1190
|
if (error.name === "NativeAuthError") {
|
@@ -1695,6 +1695,12 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1695
1695
|
silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
|
1696
1696
|
}
|
1697
1697
|
}
|
1698
|
+
if (options.proofOfPossessionOptions) {
|
1699
|
+
silentRequest.shrNonce = options.proofOfPossessionOptions.nonce;
|
1700
|
+
silentRequest.authenticationScheme = "pop";
|
1701
|
+
silentRequest.resourceRequestMethod = options.proofOfPossessionOptions.resourceRequestMethod;
|
1702
|
+
silentRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
|
1703
|
+
}
|
1698
1704
|
state.logger.getToken.info("Attempting to acquire token silently");
|
1699
1705
|
return app.acquireTokenSilent(silentRequest);
|
1700
1706
|
}
|
@@ -1753,6 +1759,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1753
1759
|
token: response.accessToken,
|
1754
1760
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
1755
1761
|
refreshAfterTimestamp: (_b = response.refreshOn) === null || _b === void 0 ? void 0 : _b.getTime(),
|
1762
|
+
tokenType: response.tokenType,
|
1756
1763
|
};
|
1757
1764
|
}
|
1758
1765
|
async function getTokenByClientSecret(scopes, clientSecret, options = {}) {
|
@@ -1773,6 +1780,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1773
1780
|
token: response.accessToken,
|
1774
1781
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
1775
1782
|
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
|
1783
|
+
tokenType: response.tokenType,
|
1776
1784
|
};
|
1777
1785
|
}
|
1778
1786
|
catch (err) {
|
@@ -1798,6 +1806,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1798
1806
|
token: response.accessToken,
|
1799
1807
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
1800
1808
|
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
|
1809
|
+
tokenType: response.tokenType,
|
1801
1810
|
};
|
1802
1811
|
}
|
1803
1812
|
catch (err) {
|
@@ -1822,6 +1831,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1822
1831
|
token: response.accessToken,
|
1823
1832
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
1824
1833
|
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
|
1834
|
+
tokenType: response.tokenType,
|
1825
1835
|
};
|
1826
1836
|
}
|
1827
1837
|
catch (err) {
|
@@ -1923,6 +1933,7 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1923
1933
|
token: response.accessToken,
|
1924
1934
|
expiresOnTimestamp: response.expiresOn.getTime(),
|
1925
1935
|
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
|
1936
|
+
tokenType: response.tokenType,
|
1926
1937
|
};
|
1927
1938
|
}
|
1928
1939
|
catch (err) {
|
@@ -1960,6 +1971,13 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1960
1971
|
else {
|
1961
1972
|
msalLogger.verbose("Attempting broker authentication without the default broker account");
|
1962
1973
|
}
|
1974
|
+
if (options.proofOfPossessionOptions) {
|
1975
|
+
interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce;
|
1976
|
+
interactiveRequest.authenticationScheme = "pop";
|
1977
|
+
interactiveRequest.resourceRequestMethod =
|
1978
|
+
options.proofOfPossessionOptions.resourceRequestMethod;
|
1979
|
+
interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
|
1980
|
+
}
|
1963
1981
|
try {
|
1964
1982
|
return await app.acquireTokenInteractive(interactiveRequest);
|
1965
1983
|
}
|
@@ -1994,6 +2012,13 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
|
|
1994
2012
|
if (state.pluginConfiguration.broker.isEnabled) {
|
1995
2013
|
return getBrokeredToken((_a = state.pluginConfiguration.broker.useDefaultBrokerAccount) !== null && _a !== void 0 ? _a : false);
|
1996
2014
|
}
|
2015
|
+
if (options.proofOfPossessionOptions) {
|
2016
|
+
interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce;
|
2017
|
+
interactiveRequest.authenticationScheme = "pop";
|
2018
|
+
interactiveRequest.resourceRequestMethod =
|
2019
|
+
options.proofOfPossessionOptions.resourceRequestMethod;
|
2020
|
+
interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
|
2021
|
+
}
|
1997
2022
|
return app.acquireTokenInteractive(interactiveRequest);
|
1998
2023
|
});
|
1999
2024
|
}
|
@@ -2338,6 +2363,7 @@ class MsalMsiProvider {
|
|
2338
2363
|
expiresOnTimestamp: token.expiresOn.getTime(),
|
2339
2364
|
token: token.accessToken,
|
2340
2365
|
refreshAfterTimestamp: (_a = token.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
|
2366
|
+
tokenType: "Bearer",
|
2341
2367
|
};
|
2342
2368
|
}
|
2343
2369
|
catch (err) {
|
@@ -2460,6 +2486,19 @@ function getScopeResource(scope) {
|
|
2460
2486
|
return scope.replace(/\/.default$/, "");
|
2461
2487
|
}
|
2462
2488
|
|
2489
|
+
// Copyright (c) Microsoft Corporation.
|
2490
|
+
// Licensed under the MIT License.
|
2491
|
+
/**
|
2492
|
+
* @internal
|
2493
|
+
*/
|
2494
|
+
function checkSubscription(logger, subscription) {
|
2495
|
+
if (!subscription.match(/^[0-9a-zA-Z-._ ]+$/)) {
|
2496
|
+
const error = new Error("Invalid subscription provided. You can locate your subscription by following the instructions listed here: https://learn.microsoft.com/azure/azure-portal/get-subscription-tenant-id.");
|
2497
|
+
logger.info(formatError("", error));
|
2498
|
+
throw error;
|
2499
|
+
}
|
2500
|
+
}
|
2501
|
+
|
2463
2502
|
// Copyright (c) Microsoft Corporation.
|
2464
2503
|
// Licensed under the MIT License.
|
2465
2504
|
/**
|
@@ -2486,11 +2525,16 @@ const cliCredentialInternals = {
|
|
2486
2525
|
* @param resource - The resource to use when getting the token
|
2487
2526
|
* @internal
|
2488
2527
|
*/
|
2489
|
-
async getAzureCliAccessToken(resource, tenantId, timeout) {
|
2528
|
+
async getAzureCliAccessToken(resource, tenantId, subscription, timeout) {
|
2490
2529
|
let tenantSection = [];
|
2530
|
+
let subscriptionSection = [];
|
2491
2531
|
if (tenantId) {
|
2492
2532
|
tenantSection = ["--tenant", tenantId];
|
2493
2533
|
}
|
2534
|
+
if (subscription) {
|
2535
|
+
// Add quotes around the subscription to handle subscriptions with spaces
|
2536
|
+
subscriptionSection = ["--subscription", `"${subscription}"`];
|
2537
|
+
}
|
2494
2538
|
return new Promise((resolve, reject) => {
|
2495
2539
|
try {
|
2496
2540
|
child_process.execFile("az", [
|
@@ -2501,6 +2545,7 @@ const cliCredentialInternals = {
|
|
2501
2545
|
"--resource",
|
2502
2546
|
resource,
|
2503
2547
|
...tenantSection,
|
2548
|
+
...subscriptionSection,
|
2504
2549
|
], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true, timeout }, (error, stdout, stderr) => {
|
2505
2550
|
resolve({ stdout: stdout, stderr: stderr, error });
|
2506
2551
|
});
|
@@ -2532,6 +2577,10 @@ class AzureCliCredential {
|
|
2532
2577
|
checkTenantId(logger$d, options === null || options === void 0 ? void 0 : options.tenantId);
|
2533
2578
|
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
|
2534
2579
|
}
|
2580
|
+
if (options === null || options === void 0 ? void 0 : options.subscription) {
|
2581
|
+
checkSubscription(logger$d, options === null || options === void 0 ? void 0 : options.subscription);
|
2582
|
+
this.subscription = options === null || options === void 0 ? void 0 : options.subscription;
|
2583
|
+
}
|
2535
2584
|
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
|
2536
2585
|
this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
|
2537
2586
|
}
|
@@ -2548,6 +2597,9 @@ class AzureCliCredential {
|
|
2548
2597
|
if (tenantId) {
|
2549
2598
|
checkTenantId(logger$d, tenantId);
|
2550
2599
|
}
|
2600
|
+
if (this.subscription) {
|
2601
|
+
checkSubscription(logger$d, this.subscription);
|
2602
|
+
}
|
2551
2603
|
const scope = typeof scopes === "string" ? scopes : scopes[0];
|
2552
2604
|
logger$d.getToken.info(`Using the scope ${scope}`);
|
2553
2605
|
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
|
@@ -2555,7 +2607,7 @@ class AzureCliCredential {
|
|
2555
2607
|
try {
|
2556
2608
|
ensureValidScopeForDevTimeCreds(scope, logger$d);
|
2557
2609
|
const resource = getScopeResource(scope);
|
2558
|
-
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId, this.timeout);
|
2610
|
+
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId, this.subscription, this.timeout);
|
2559
2611
|
const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
|
2560
2612
|
const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
|
2561
2613
|
const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
|
@@ -2612,6 +2664,7 @@ class AzureCliCredential {
|
|
2612
2664
|
return {
|
2613
2665
|
token,
|
2614
2666
|
expiresOnTimestamp,
|
2667
|
+
tokenType: "Bearer",
|
2615
2668
|
};
|
2616
2669
|
}
|
2617
2670
|
// fallback to the older expiresOn - an RFC3339 date string
|
@@ -2623,6 +2676,7 @@ class AzureCliCredential {
|
|
2623
2676
|
return {
|
2624
2677
|
token,
|
2625
2678
|
expiresOnTimestamp,
|
2679
|
+
tokenType: "Bearer",
|
2626
2680
|
};
|
2627
2681
|
}
|
2628
2682
|
}
|
@@ -2771,6 +2825,7 @@ class AzureDeveloperCliCredential {
|
|
2771
2825
|
return {
|
2772
2826
|
token: resp.token,
|
2773
2827
|
expiresOnTimestamp: new Date(resp.expiresOn).getTime(),
|
2828
|
+
tokenType: "Bearer",
|
2774
2829
|
};
|
2775
2830
|
}
|
2776
2831
|
catch (e) {
|
@@ -2991,6 +3046,7 @@ class AzurePowerShellCredential {
|
|
2991
3046
|
return {
|
2992
3047
|
token: response.Token,
|
2993
3048
|
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
|
3049
|
+
tokenType: "Bearer",
|
2994
3050
|
};
|
2995
3051
|
}
|
2996
3052
|
catch (err) {
|
@@ -3051,8 +3107,9 @@ async function parseJsonToken(result) {
|
|
3051
3107
|
*/
|
3052
3108
|
const logger$a = credentialLogger("ChainedTokenCredential");
|
3053
3109
|
/**
|
3054
|
-
* Enables multiple `TokenCredential` implementations to be tried in order
|
3055
|
-
*
|
3110
|
+
* Enables multiple `TokenCredential` implementations to be tried in order until
|
3111
|
+
* one of the getToken methods returns an access token. For more information, see
|
3112
|
+
* [ChainedTokenCredential overview](https://aka.ms/azsdk/js/identity/credential-chains#use-chainedtokencredential-for-granularity).
|
3056
3113
|
*/
|
3057
3114
|
class ChainedTokenCredential {
|
3058
3115
|
/**
|
@@ -3061,7 +3118,14 @@ class ChainedTokenCredential {
|
|
3061
3118
|
* @param sources - `TokenCredential` implementations to be tried in order.
|
3062
3119
|
*
|
3063
3120
|
* Example usage:
|
3064
|
-
* ```
|
3121
|
+
* ```ts snippet:chained_token_credential_example
|
3122
|
+
* import { ClientSecretCredential, ChainedTokenCredential } from "@azure/identity";
|
3123
|
+
*
|
3124
|
+
* const tenantId = "<tenant-id>";
|
3125
|
+
* const clientId = "<client-id>";
|
3126
|
+
* const clientSecret = "<client-secret>";
|
3127
|
+
* const anotherClientId = "<another-client-id>";
|
3128
|
+
* const anotherSecret = "<another-client-secret>";
|
3065
3129
|
* const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
|
3066
3130
|
* const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
|
3067
3131
|
* const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
|
@@ -3586,8 +3650,21 @@ class UnavailableDefaultCredential {
|
|
3586
3650
|
}
|
3587
3651
|
}
|
3588
3652
|
/**
|
3589
|
-
* Provides a default {@link ChainedTokenCredential} configuration that
|
3590
|
-
*
|
3653
|
+
* Provides a default {@link ChainedTokenCredential} configuration that works for most
|
3654
|
+
* applications that use Azure SDK client libraries. For more information, see
|
3655
|
+
* [DefaultAzureCredential overview](https://aka.ms/azsdk/js/identity/credential-chains#use-defaultazurecredential-for-flexibility).
|
3656
|
+
*
|
3657
|
+
* The following credential types will be tried, in order:
|
3658
|
+
*
|
3659
|
+
* - {@link EnvironmentCredential}
|
3660
|
+
* - {@link WorkloadIdentityCredential}
|
3661
|
+
* - {@link ManagedIdentityCredential}
|
3662
|
+
* - {@link AzureCliCredential}
|
3663
|
+
* - {@link AzurePowerShellCredential}
|
3664
|
+
* - {@link AzureDeveloperCliCredential}
|
3665
|
+
*
|
3666
|
+
* Consult the documentation of these credential types for more information
|
3667
|
+
* on how they attempt authentication.
|
3591
3668
|
*/
|
3592
3669
|
class DefaultAzureCredential extends ChainedTokenCredential {
|
3593
3670
|
constructor(options) {
|
@@ -3725,13 +3802,15 @@ class DeviceCodeCredential {
|
|
3725
3802
|
*
|
3726
3803
|
* Developers can configure how this message is shown by passing a custom `userPromptCallback`:
|
3727
3804
|
*
|
3728
|
-
* ```
|
3805
|
+
* ```ts snippet:device_code_credential_example
|
3806
|
+
* import { DeviceCodeCredential } from "@azure/identity";
|
3807
|
+
*
|
3729
3808
|
* const credential = new DeviceCodeCredential({
|
3730
|
-
* tenantId: env.AZURE_TENANT_ID,
|
3731
|
-
* clientId: env.AZURE_CLIENT_ID,
|
3809
|
+
* tenantId: process.env.AZURE_TENANT_ID,
|
3810
|
+
* clientId: process.env.AZURE_CLIENT_ID,
|
3732
3811
|
* userPromptCallback: (info) => {
|
3733
3812
|
* console.log("CUSTOMIZED PROMPT CALLBACK", info.message);
|
3734
|
-
* }
|
3813
|
+
* },
|
3735
3814
|
* });
|
3736
3815
|
* ```
|
3737
3816
|
*
|
@@ -3803,7 +3882,8 @@ class AzurePipelinesCredential {
|
|
3803
3882
|
* @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.
|
3804
3883
|
* @param options - The identity client options to use for authentication.
|
3805
3884
|
*/
|
3806
|
-
constructor(tenantId, clientId, serviceConnectionId, systemAccessToken, options) {
|
3885
|
+
constructor(tenantId, clientId, serviceConnectionId, systemAccessToken, options = {}) {
|
3886
|
+
var _a, _b;
|
3807
3887
|
if (!clientId) {
|
3808
3888
|
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. clientId is a required parameter.`);
|
3809
3889
|
}
|
@@ -3816,6 +3896,12 @@ class AzurePipelinesCredential {
|
|
3816
3896
|
if (!systemAccessToken) {
|
3817
3897
|
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. systemAccessToken is a required parameter.`);
|
3818
3898
|
}
|
3899
|
+
// Allow these headers to be logged for troubleshooting by AzurePipelines.
|
3900
|
+
options.loggingOptions = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.loggingOptions), { additionalAllowedHeaderNames: [
|
3901
|
+
...((_b = (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.additionalAllowedHeaderNames) !== null && _b !== void 0 ? _b : []),
|
3902
|
+
"x-vss-e2eid",
|
3903
|
+
"x-msedge-ref",
|
3904
|
+
] });
|
3819
3905
|
this.identityClient = new IdentityClient(options);
|
3820
3906
|
checkTenantId(logger$2, tenantId);
|
3821
3907
|
logger$2.info(`Invoking AzurePipelinesCredential with tenant ID: ${tenantId}, client ID: ${clientId}, and service connection ID: ${serviceConnectionId}`);
|
@@ -3864,6 +3950,8 @@ class AzurePipelinesCredential {
|
|
3864
3950
|
headers: coreRestPipeline.createHttpHeaders({
|
3865
3951
|
"Content-Type": "application/json",
|
3866
3952
|
Authorization: `Bearer ${systemAccessToken}`,
|
3953
|
+
// Prevents the service from responding with a redirect HTTP status code (useful for automation).
|
3954
|
+
"X-TFS-FedAuthRedirect": "Suppress",
|
3867
3955
|
}),
|
3868
3956
|
});
|
3869
3957
|
const response = await this.identityClient.sendRequest(request);
|
@@ -3871,6 +3959,7 @@ class AzurePipelinesCredential {
|
|
3871
3959
|
}
|
3872
3960
|
}
|
3873
3961
|
function handleOidcResponse(response) {
|
3962
|
+
// OIDC token is present in `bodyAsText` field
|
3874
3963
|
const text = response.bodyAsText;
|
3875
3964
|
if (!text) {
|
3876
3965
|
logger$2.error(`${credentialName$1}: Authentication Failed. Received null token from OIDC request. Response status- ${response.status}. Complete response - ${JSON.stringify(response)}`);
|
@@ -3888,7 +3977,7 @@ function handleOidcResponse(response) {
|
|
3888
3977
|
const errorMessage = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
3889
3978
|
let errorDescription = ``;
|
3890
3979
|
if (response.status !== 200) {
|
3891
|
-
errorDescription = `
|
3980
|
+
errorDescription = `Response body = ${text}. Response Headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")} and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`;
|
3892
3981
|
}
|
3893
3982
|
logger$2.error(errorMessage);
|
3894
3983
|
logger$2.error(errorDescription);
|
@@ -3900,11 +3989,12 @@ function handleOidcResponse(response) {
|
|
3900
3989
|
}
|
3901
3990
|
catch (e) {
|
3902
3991
|
const errorDetails = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
3903
|
-
logger$2.error(`Response from service = ${text}
|
3992
|
+
logger$2.error(`Response from service = ${text}, Response Headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")}
|
3993
|
+
and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}, error message = ${e.message}`);
|
3904
3994
|
logger$2.error(errorDetails);
|
3905
3995
|
throw new AuthenticationError(response.status, {
|
3906
3996
|
error: errorDetails,
|
3907
|
-
error_description: `Response = ${text}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
|
3997
|
+
error_description: `Response = ${text}. Response headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")} and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
|
3908
3998
|
});
|
3909
3999
|
}
|
3910
4000
|
}
|
@@ -4072,14 +4162,14 @@ class OnBehalfOfCredential {
|
|
4072
4162
|
/**
|
4073
4163
|
* Returns a callback that provides a bearer token.
|
4074
4164
|
* For example, the bearer token can be used to authenticate a request as follows:
|
4075
|
-
* ```
|
4076
|
-
* import { DefaultAzureCredential } from "@azure/identity";
|
4165
|
+
* ```ts snippet:token_provider_example
|
4166
|
+
* import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
|
4167
|
+
* import { createPipelineRequest } from "@azure/core-rest-pipeline";
|
4077
4168
|
*
|
4078
4169
|
* const credential = new DefaultAzureCredential();
|
4079
4170
|
* const scope = "https://cognitiveservices.azure.com/.default";
|
4080
4171
|
* const getAccessToken = getBearerTokenProvider(credential, scope);
|
4081
4172
|
* const token = await getAccessToken();
|
4082
|
-
*
|
4083
4173
|
* // usage
|
4084
4174
|
* const request = createPipelineRequest({ url: "https://example.com" });
|
4085
4175
|
* request.headers.set("Authorization", `Bearer ${token}`);
|