Hello! Welcome back to your AZ-204 preparation.
In our last two lessons, we established the foundation for secure, passwordless authentication. First, we created an identity for your application by enabling a system-assigned managed identity on your App Service. Then, we granted that identity permission to read secrets from an Azure Key Vault by configuring an access policy.
Today, we complete the circuit. We will connect that infrastructure setup to your application code. The learning outcome for this lesson is to configure an application to authenticate to Azure services using its managed identity and the DefaultAzureCredential class. You'll see how your C# and .NET expertise makes it straightforward to write code that is both powerful and secure.
By the end of this lesson, you'll be able to refactor a .NET application to remove hardcoded secrets and connect to Azure services like Storage and Key Vault using the modern, recommended authentication pattern.
1. The Challenge of Credentials and the DefaultAzureCredential Solution
As a developer, you know the pain of managing secrets: local development connection strings, test environment passwords, production keys. Storing them in appsettings.json is a security risk, and managing them through environment variables can be cumbersome across different deployment stages.
The Azure.Identity library for .NET provides an elegant solution. Its central component is the DefaultAzureCredential class. Instead of telling your code how to authenticate, you simply create an instance of DefaultAzureCredential, and it automatically figures out the best way to authenticate based on the environment where it's running.
This works through a "chain of credentials." DefaultAzureCredential tries a sequence of authentication methods until one succeeds.

This means:
- In Azure (Production): The code will automatically use the App Service's managed identity that we configured.
- On your local machine (Development): The code will use the credentials from your Azure CLI login (
az login) or your Visual Studio Azure account.
The result is a single, clean codebase that works everywhere without modification and without containing any secrets.
To solidify this foundational concept, let's review a short article that explains it in detail.
How to Authenticate with Azure Services Using Azure.Identity in C# .NET
The article 'How to Authenticate with Azure Services Using Azure.Identity in C# .NET' provides an excellent overview of DefaultAzureCredential.
Please read the sections titled 'DefaultAzureCredential Basics', 'Local Development Setup', and 'Managed Identity in Production'. Pay close attention to the credential chain and how the same code works in both your local environment and in Azure.
2. Hands-On: Refactoring a .NET App to Use DefaultAzureCredential
Now, let's put theory into practice. We'll refactor a .NET web application to access Azure Blob Storage using its managed identity, completely removing the storage connection string.
The following video provides a clear walkthrough of this exact process.
Managed Identity [5 of 8] | .NET on Azure for Beginners
This clip from the official .NET channel's '.NET on Azure for Beginners' series demonstrates the key code changes to adopt DefaultAzureCredential.
Watch from 00:10:45 to 00:15:39. Observe the three key steps: deleting the connection string, adding the Azure.Identity NuGet package, and modifying Program.cs to instantiate the BlobServiceClient with DefaultAzureCredential.
Your Turn: Let's Write the Code
Follow these steps in a sample .NET 6 (or later) web app project.
Prerequisites:
- An Azure App Service with a system-assigned managed identity enabled.
- An Azure Storage Account.
- Grant the App Service's managed identity the "Storage Blob Data Contributor" role on the Storage Account. You can do this in the Storage Account's Access Control (IAM) blade, similar to how you granted Key Vault permissions in the last lesson.
- On your local machine, make sure you are logged into the Azure CLI (
az login).
Step 1: Update Project Dependencies
In your project's directory, run the following commands to install the necessary NuGet packages:
dotnet add package Azure.Identity
dotnet add package Azure.Storage.Blobs
Step 2: Update appsettings.json
Remove any storage connection strings. Instead, add the URI for your storage account's blob service. You can find this on your Storage Account's Endpoints page in the Azure portal.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"StorageUri": "https://<your-storage-account-name>.blob.core.windows.net/"
}
Step 3: Modify Program.cs for Dependency Injection
We will use dependency injection to provide the BlobServiceClient to our application, which is a standard pattern in modern .NET development.
using Azure.Identity;
using Azure.Storage.Blobs;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
// --- START: Add Azure Client ---
// Get the Blob Storage URI from configuration
var storageUri = new Uri(builder.Configuration["StorageUri"]);
// Register the BlobServiceClient for DI.
// It will use DefaultAzureCredential for authentication.
builder.Services.AddSingleton(new BlobServiceClient(storageUri, new DefaultAzureCredential()));
// --- END: Add Azure Client ---
var app = builder.Build();
// ... (rest of Program.cs)
// Example of using the client in a minimal API endpoint
app.MapGet("/blobs", async (BlobServiceClient client) =>
{
var containers = new List<string>();
await foreach (var container in client.GetBlobContainersAsync())
{
containers.Add(container.Name);
}
return containers;
});
app.Run();
Step 4: Test Locally and in Azure
- Run Locally: Start your application from Visual Studio or with
dotnet run. Navigate to the/blobsendpoint. It should successfully connect and list your blob containers, authenticating using youraz logincredentials. - Deploy to Azure: Publish your application to the App Service.
- Test in Azure: Browse to your deployed application's
/blobsendpoint. It will work again, but this timeDefaultAzureCredentialis using the App Service's managed identity.
You have successfully implemented a secure, credential-free solution that works across environments!
3. Applying the Pattern to Azure Key Vault
The beauty of this pattern is its consistency. Connecting to Key Vault follows the exact same logic. In the previous lesson, we granted your managed identity access to a Key Vault. Now, here's the code to retrieve a secret.
The process is identical: install the client library, get the resource URI, and create the client using DefaultAzureCredential.
Tutorial - Use Azure Key Vault with an Azure web app in .NET
This official Microsoft tutorial confirms the pattern by showing the code changes needed to connect an app to Key Vault.
Read the section titled 'Modify the app to access your key vault'. Note how it mirrors our storage example: you install the Azure.Security.KeyVault.Secrets package and create a SecretClient with DefaultAzureCredential.
To integrate this into your Program.cs, you would first run:dotnet add package Azure.Security.KeyVault.Secrets
Then, you would register the SecretClient for dependency injection:
// Program.cs
// (Add these lines alongside your BlobServiceClient registration)
// Get Key Vault URI from appsettings.json
var keyVaultUri = new Uri(builder.Configuration["KeyVaultUri"]);
// Register SecretClient for DI
builder.Services.AddSingleton(new SecretClient(keyVaultUri, new DefaultAzureCredential()));
From any controller or minimal API endpoint, you can now inject SecretClient and use it to retrieve secrets, just as we did with BlobServiceClient.
Conclusion
In this lesson, you mastered one of the most important security patterns for Azure development. You connected the infrastructure we've been building directly to your C# application code.
Key Takeaways:
- The
Azure.Identitylibrary and itsDefaultAzureCredentialclass are the cornerstones of modern, secure authentication in the Azure .NET SDK. DefaultAzureCredentialuses a credential chain to automatically authenticate in different environments, enabling a single codebase for both local development and Azure deployments.- The pattern is consistent across Azure services: instantiate the specific service client (e.g.,
BlobServiceClient,SecretClient) and pass it anew DefaultAzureCredential()object. - This approach completely eliminates secrets and connection strings from your application's source code and configuration, dramatically improving your security posture.
Next Steps
Now that you understand the full end-to-end flow—from enabling an identity to granting permissions to using it in code—we'll circle back to focus on managing the Key Vault itself. In the next lesson, we will dive deep into how to create a Key Vault and manage its secrets entirely from the Azure CLI, a critical skill for automating your secure infrastructure.