@azure/identity 4.5.0-beta.3 → 4.5.0
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 +72 -22
- 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 +2 -0
- package/dist-esm/src/credentials/azureCliCredential.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 +8 -1
- 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/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/package.json +17 -16
- package/types/identity.d.ts +53 -47
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.0
|
47
|
+
const SDK_VERSION = `4.5.0`;
|
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) {
|
@@ -2612,6 +2638,7 @@ class AzureCliCredential {
|
|
2612
2638
|
return {
|
2613
2639
|
token,
|
2614
2640
|
expiresOnTimestamp,
|
2641
|
+
tokenType: "Bearer",
|
2615
2642
|
};
|
2616
2643
|
}
|
2617
2644
|
// fallback to the older expiresOn - an RFC3339 date string
|
@@ -2623,6 +2650,7 @@ class AzureCliCredential {
|
|
2623
2650
|
return {
|
2624
2651
|
token,
|
2625
2652
|
expiresOnTimestamp,
|
2653
|
+
tokenType: "Bearer",
|
2626
2654
|
};
|
2627
2655
|
}
|
2628
2656
|
}
|
@@ -2771,6 +2799,7 @@ class AzureDeveloperCliCredential {
|
|
2771
2799
|
return {
|
2772
2800
|
token: resp.token,
|
2773
2801
|
expiresOnTimestamp: new Date(resp.expiresOn).getTime(),
|
2802
|
+
tokenType: "Bearer",
|
2774
2803
|
};
|
2775
2804
|
}
|
2776
2805
|
catch (e) {
|
@@ -2991,6 +3020,7 @@ class AzurePowerShellCredential {
|
|
2991
3020
|
return {
|
2992
3021
|
token: response.Token,
|
2993
3022
|
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
|
3023
|
+
tokenType: "Bearer",
|
2994
3024
|
};
|
2995
3025
|
}
|
2996
3026
|
catch (err) {
|
@@ -3061,7 +3091,14 @@ class ChainedTokenCredential {
|
|
3061
3091
|
* @param sources - `TokenCredential` implementations to be tried in order.
|
3062
3092
|
*
|
3063
3093
|
* Example usage:
|
3064
|
-
* ```
|
3094
|
+
* ```ts snippet:chained_token_credential_example
|
3095
|
+
* import { ClientSecretCredential, ChainedTokenCredential } from "@azure/identity";
|
3096
|
+
*
|
3097
|
+
* const tenantId = "<tenant-id>";
|
3098
|
+
* const clientId = "<client-id>";
|
3099
|
+
* const clientSecret = "<client-secret>";
|
3100
|
+
* const anotherClientId = "<another-client-id>";
|
3101
|
+
* const anotherSecret = "<another-client-secret>";
|
3065
3102
|
* const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
|
3066
3103
|
* const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
|
3067
3104
|
* const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
|
@@ -3725,13 +3762,15 @@ class DeviceCodeCredential {
|
|
3725
3762
|
*
|
3726
3763
|
* Developers can configure how this message is shown by passing a custom `userPromptCallback`:
|
3727
3764
|
*
|
3728
|
-
* ```
|
3765
|
+
* ```ts snippet:device_code_credential_example
|
3766
|
+
* import { DeviceCodeCredential } from "@azure/identity";
|
3767
|
+
*
|
3729
3768
|
* const credential = new DeviceCodeCredential({
|
3730
|
-
* tenantId: env.AZURE_TENANT_ID,
|
3731
|
-
* clientId: env.AZURE_CLIENT_ID,
|
3769
|
+
* tenantId: process.env.AZURE_TENANT_ID,
|
3770
|
+
* clientId: process.env.AZURE_CLIENT_ID,
|
3732
3771
|
* userPromptCallback: (info) => {
|
3733
3772
|
* console.log("CUSTOMIZED PROMPT CALLBACK", info.message);
|
3734
|
-
* }
|
3773
|
+
* },
|
3735
3774
|
* });
|
3736
3775
|
* ```
|
3737
3776
|
*
|
@@ -3803,7 +3842,8 @@ class AzurePipelinesCredential {
|
|
3803
3842
|
* @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
3843
|
* @param options - The identity client options to use for authentication.
|
3805
3844
|
*/
|
3806
|
-
constructor(tenantId, clientId, serviceConnectionId, systemAccessToken, options) {
|
3845
|
+
constructor(tenantId, clientId, serviceConnectionId, systemAccessToken, options = {}) {
|
3846
|
+
var _a, _b;
|
3807
3847
|
if (!clientId) {
|
3808
3848
|
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. clientId is a required parameter.`);
|
3809
3849
|
}
|
@@ -3816,6 +3856,12 @@ class AzurePipelinesCredential {
|
|
3816
3856
|
if (!systemAccessToken) {
|
3817
3857
|
throw new CredentialUnavailableError(`${credentialName$1}: is unavailable. systemAccessToken is a required parameter.`);
|
3818
3858
|
}
|
3859
|
+
// Allow these headers to be logged for troubleshooting by AzurePipelines.
|
3860
|
+
options.loggingOptions = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.loggingOptions), { additionalAllowedHeaderNames: [
|
3861
|
+
...((_b = (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.additionalAllowedHeaderNames) !== null && _b !== void 0 ? _b : []),
|
3862
|
+
"x-vss-e2eid",
|
3863
|
+
"x-msedge-ref",
|
3864
|
+
] });
|
3819
3865
|
this.identityClient = new IdentityClient(options);
|
3820
3866
|
checkTenantId(logger$2, tenantId);
|
3821
3867
|
logger$2.info(`Invoking AzurePipelinesCredential with tenant ID: ${tenantId}, client ID: ${clientId}, and service connection ID: ${serviceConnectionId}`);
|
@@ -3864,6 +3910,8 @@ class AzurePipelinesCredential {
|
|
3864
3910
|
headers: coreRestPipeline.createHttpHeaders({
|
3865
3911
|
"Content-Type": "application/json",
|
3866
3912
|
Authorization: `Bearer ${systemAccessToken}`,
|
3913
|
+
// Prevents the service from responding with a redirect HTTP status code (useful for automation).
|
3914
|
+
"X-TFS-FedAuthRedirect": "Suppress",
|
3867
3915
|
}),
|
3868
3916
|
});
|
3869
3917
|
const response = await this.identityClient.sendRequest(request);
|
@@ -3871,6 +3919,7 @@ class AzurePipelinesCredential {
|
|
3871
3919
|
}
|
3872
3920
|
}
|
3873
3921
|
function handleOidcResponse(response) {
|
3922
|
+
// OIDC token is present in `bodyAsText` field
|
3874
3923
|
const text = response.bodyAsText;
|
3875
3924
|
if (!text) {
|
3876
3925
|
logger$2.error(`${credentialName$1}: Authentication Failed. Received null token from OIDC request. Response status- ${response.status}. Complete response - ${JSON.stringify(response)}`);
|
@@ -3888,7 +3937,7 @@ function handleOidcResponse(response) {
|
|
3888
3937
|
const errorMessage = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
3889
3938
|
let errorDescription = ``;
|
3890
3939
|
if (response.status !== 200) {
|
3891
|
-
errorDescription = `
|
3940
|
+
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
3941
|
}
|
3893
3942
|
logger$2.error(errorMessage);
|
3894
3943
|
logger$2.error(errorDescription);
|
@@ -3900,11 +3949,12 @@ function handleOidcResponse(response) {
|
|
3900
3949
|
}
|
3901
3950
|
catch (e) {
|
3902
3951
|
const errorDetails = `${credentialName$1}: Authentication Failed. oidcToken field not detected in the response.`;
|
3903
|
-
logger$2.error(`Response from service = ${text}
|
3952
|
+
logger$2.error(`Response from service = ${text}, Response Headers ["x-vss-e2eid"] = ${response.headers.get("x-vss-e2eid")}
|
3953
|
+
and ["x-msedge-ref"] = ${response.headers.get("x-msedge-ref")}, error message = ${e.message}`);
|
3904
3954
|
logger$2.error(errorDetails);
|
3905
3955
|
throw new AuthenticationError(response.status, {
|
3906
3956
|
error: errorDetails,
|
3907
|
-
error_description: `Response = ${text}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
|
3957
|
+
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
3958
|
});
|
3909
3959
|
}
|
3910
3960
|
}
|
@@ -4072,14 +4122,14 @@ class OnBehalfOfCredential {
|
|
4072
4122
|
/**
|
4073
4123
|
* Returns a callback that provides a bearer token.
|
4074
4124
|
* For example, the bearer token can be used to authenticate a request as follows:
|
4075
|
-
* ```
|
4076
|
-
* import { DefaultAzureCredential } from "@azure/identity";
|
4125
|
+
* ```ts snippet:token_provider_example
|
4126
|
+
* import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
|
4127
|
+
* import { createPipelineRequest } from "@azure/core-rest-pipeline";
|
4077
4128
|
*
|
4078
4129
|
* const credential = new DefaultAzureCredential();
|
4079
4130
|
* const scope = "https://cognitiveservices.azure.com/.default";
|
4080
4131
|
* const getAccessToken = getBearerTokenProvider(credential, scope);
|
4081
4132
|
* const token = await getAccessToken();
|
4082
|
-
*
|
4083
4133
|
* // usage
|
4084
4134
|
* const request = createPipelineRequest({ url: "https://example.com" });
|
4085
4135
|
* request.headers.set("Authorization", `Bearer ${token}`);
|