Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
This article offers guidelines to help you maximize the performance and reliability of your .NET apps when authenticating to Azure services. To make the most of the Azure Identity library for .NET, it's important to understand potential issues and mitigation techniques.
DefaultAzureCredential
is the most approachable way to get started with the Azure Identity library, but that convenience also introduces certain tradeoffs. Most notably, the specific credential in the chain that will succeed and be used for request authentication can't be guaranteed ahead of time. In a production environment, this unpredictability can introduce significant and sometimes subtle problems.
For example, consider the following hypothetical sequence of events:
DefaultAzureCredential
to authenticate via managed identity.az login
command to authenticate to Azure.DefaultAzureCredential
skips the failed ManagedIdentityCredential
and searches for the next available credential, which is AzureCliCredential
.To prevent these types of subtle issues or silent failures in production apps, replace DefaultAzureCredential
with a specific TokenCredential
implementation, such as ManagedIdentityCredential
. See the Derived list for options.
For example, consider the following DefaultAzureCredential
configuration in an ASP.NET Core project:
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
DefaultAzureCredential credential = new();
clientBuilder.UseCredential(credential);
});
Modify the preceding code to select a credential based on the environment in which the app is running:
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
TokenCredential credential;
if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
{
string? clientId = builder.Configuration["UserAssignedClientId"];
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(clientId));
}
else
{
// local development environment
credential = new ChainedTokenCredential(
new VisualStudioCredential(),
new AzureCliCredential(),
new AzurePowerShellCredential());
}
clientBuilder.UseCredential(credential);
});
In this example, only ManagedIdentityCredential
is used in production. The local development environment's authentication needs are then serviced by the sequence of credentials defined in the else
clause.
Reuse credential instances when possible to improve app resilience and reduce the number of access token requests issued to Microsoft Entra ID. When a credential is reused, an attempt is made to fetch a token from the app token cache managed by the underlying MSAL dependency. For more information, see Token caching in the Azure Identity client library.
Important
A high-volume app that doesn't reuse credentials may encounter HTTP 429 throttling responses from Microsoft Entra ID, which can lead to app outages.
The recommended credential reuse strategy differs by .NET application type.
To implement credential reuse, use the UseCredential method from Microsoft.Extensions.Azure
. Consider an ASP.NET Core app hosted on Azure App Service in both production and staging environments. Environment variable ASPNETCORE_ENVIRONMENT
is set to either Production
or Staging
to differentiate between these two non-development environments. In both production and staging, the user-assigned variant of ManagedIdentityCredential
is used to authenticate the Key Vault Secrets and Blob Storage clients.
When the app runs on a local development machine, where ASPNETCORE_ENVIRONMENT
is set to Development
, a chained sequence of developer tool credentials is used instead. This approach ensures environment-appropriate credentials are used, enhancing security and simplifying credential management.
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
TokenCredential credential;
if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
{
string? clientId = builder.Configuration["UserAssignedClientId"];
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(clientId));
}
else
{
// local development environment
credential = new ChainedTokenCredential(
new VisualStudioCredential(),
new AzureCliCredential(),
new AzurePowerShellCredential());
}
clientBuilder.UseCredential(credential);
});
For information on this approach in an ASP.NET Core app, see Authenticate using Microsoft Entra ID.
If you use an Azure Identity library credential outside the context of an Azure SDK client library that depends on Azure Core, it becomes your responsibility to manage token lifetime and caching behavior in your app.
The RefreshOn property on AccessToken
, which provides a hint to consumers as to when token refresh can be attempted, will be automatically used by Azure SDK client libraries that depend on the Azure Core library to refresh the token. For direct usage of Azure Identity library credentials that support token caching, the underlying MSAL cache automatically refreshes proactively when the RefreshOn
time occurs. This design allows the client code to call GetToken
each time a token is needed and delegate the refresh to the library.
To only call GetToken
when necessary, observe the RefreshOn
date and proactively attempt to refresh the token after that time. The specific implementation is up to the customer.
The Azure Identity library for .NET allows you to authenticate via managed identity with ManagedIdentityCredential
. The way in which you use ManagedIdentityCredential
impacts the applied retry strategy. When used via:
DefaultAzureCredential
, no retries are attempted when the initial token acquisition attempt fails or times out after a short duration. This is the least resilient option because it's optimized to "fail fast" for an efficient development inner loop.ChainedTokenCredential
or ManagedIdentityCredential
directly:
The time interval between retries starts at 0.8 seconds, and a maximum of five retries are attempted, by default. This option is optimized for resilience but introduces potentially unwanted delays in the development inner loop.
To change any of the default retry settings, use the Retry
property on ManagedIdentityCredentialOptions
. For example, retry a maximum of three times, with a starting interval of 0.5 seconds:
ManagedIdentityCredentialOptions miCredentialOptions = new(
ManagedIdentityId.FromUserAssignedClientId(clientId)
)
{
Retry =
{
MaxRetries = 3,
Delay = TimeSpan.FromSeconds(0.5),
}
};
ManagedIdentityCredential miCredential = new(miCredentialOptions);
For more information on customizing retry policies, see Setting a custom retry policy.
.NET feedback
.NET is an open source project. Select a link to provide feedback:
Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Module
Introduction to using Managed Identity to authenticate to Azure OpenAI with .NET - Training
How to implement role based access control and managed identity authentication to Azure OpenAI with .NET.
Documentation
How to authenticate .NET applications with Azure services - .NET
Learn how to authenticate a .NET app with Azure services by using classes in the Azure Identity library.
Authenticate .NET apps to Azure using developer accounts - .NET
Learn how to authenticate your application to Azure services when using the Azure SDK for .NET during local development using developer accounts.
Credential chains in the Azure Identity library for .NET - .NET
This article describes the DefaultAzureCredential and ChainedTokenCredential classes in the Azure Identity library.