@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.
Files changed (40) hide show
  1. package/README.md +28 -33
  2. package/dist/index.js +72 -22
  3. package/dist/index.js.map +1 -1
  4. package/dist-esm/src/client/identityClient.js +1 -0
  5. package/dist-esm/src/client/identityClient.js.map +1 -1
  6. package/dist-esm/src/constants.js +1 -1
  7. package/dist-esm/src/constants.js.map +1 -1
  8. package/dist-esm/src/credentials/azureCliCredential.js +2 -0
  9. package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
  10. package/dist-esm/src/credentials/azureDeveloperCliCredential.js +1 -0
  11. package/dist-esm/src/credentials/azureDeveloperCliCredential.js.map +1 -1
  12. package/dist-esm/src/credentials/azurePipelinesCredential.js +15 -4
  13. package/dist-esm/src/credentials/azurePipelinesCredential.js.map +1 -1
  14. package/dist-esm/src/credentials/azurePowerShellCredential.js +1 -0
  15. package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
  16. package/dist-esm/src/credentials/chainedTokenCredential.js +8 -1
  17. package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
  18. package/dist-esm/src/credentials/credentialPersistenceOptions.js.map +1 -1
  19. package/dist-esm/src/credentials/deviceCodeCredential.js +6 -4
  20. package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
  21. package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
  22. package/dist-esm/src/credentials/managedIdentityCredential/legacyMsiProvider.js +1 -0
  23. package/dist-esm/src/credentials/managedIdentityCredential/legacyMsiProvider.js.map +1 -1
  24. package/dist-esm/src/credentials/managedIdentityCredential/msalMsiProvider.js +1 -0
  25. package/dist-esm/src/credentials/managedIdentityCredential/msalMsiProvider.js.map +1 -1
  26. package/dist-esm/src/credentials/onBehalfOfCredential.js.map +1 -1
  27. package/dist-esm/src/msal/browserFlows/msalAuthCode.js +1 -1
  28. package/dist-esm/src/msal/browserFlows/msalAuthCode.js.map +1 -1
  29. package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js +1 -0
  30. package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js.map +1 -1
  31. package/dist-esm/src/msal/nodeFlows/msalClient.js +25 -0
  32. package/dist-esm/src/msal/nodeFlows/msalClient.js.map +1 -1
  33. package/dist-esm/src/msal/utils.js +2 -1
  34. package/dist-esm/src/msal/utils.js.map +1 -1
  35. package/dist-esm/src/plugins/consumer.js +6 -8
  36. package/dist-esm/src/plugins/consumer.js.map +1 -1
  37. package/dist-esm/src/tokenProvider.js +3 -3
  38. package/dist-esm/src/tokenProvider.js.map +1 -1
  39. package/package.json +17 -16
  40. 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 cases, developers may want full control of the authentication protocol. For that use case, we recommend using [Microsoft Authentication Library for JavaScript (MSAL.js)](https://github.com/AzureAD/microsoft-authentication-library-for-js) directly. You can read more through the following links:
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` is appropriate for most scenarios where the application is intended to ultimately be run in Azure. This is because `DefaultAzureCredential` combines credentials commonly used to authenticate when deployed with credentials used to authenticate in a development environment.
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
- ```javascript
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
- ```typescript
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
- ```typescript
218
- import { AzureAuthorityHosts, ClientSecretCredential } from "@azure/identity";
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
- ```typescript
238
- import { AzureAuthorityHosts, ClientSecretCredential } from "@azure/identity";
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-beta.3`;
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
- * ```javascript
1021
- * import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
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 DefaultAzureCredential({
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
- * ```javascript
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
- * ```js
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 = `Complete response - ${JSON.stringify(result)}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`;
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} and error message = ${e.message}`);
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
- * ```js
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}`);