Author avatar

Benney Au

How to Use Managed Identities with Azure Blob and Queue Storage

Benney Au

  • Oct 16, 2020
  • 7 Min read
  • 70 Views
  • Oct 16, 2020
  • 7 Min read
  • 70 Views
Data
Azure Blob Storage
Data Engineering
Cloud Platforms

Introduction

Azure Blob and Queue Storage is a low-cost solution to store and access unstructured data at scale. Queues integrate easily with managed identities, which are appealing because secrets such as connection strings are not required to be copied onto developers’ machines or checked into source control. In this guide, you will learn how to use managed identities to connect a .NET app service to Azure Blob Storage and Azure Queue Storage.

Managed Identities

In Azure, a managed identity allows an Azure resource to have an identity created for it automatically in Azure Active Directory (AD). This allows these resources to identify themselves to other protected Azure resources, such as storage accounts, using Azure AD authentication. This guide will look at using managed identities with Azure App Services.

Azure App Services supports both user-assigned and system-assigned managed identities. There are a few differences:

  • System-assigned identities are linked to the lifecycle of Azure App Service. This means that when you delete the app service, its managed identities will also be deleted for you. Only a specific app service can identify itself as a specific user identity. This means that each deployment slot receives its own system-assigned identity.
  • User-assigned identities are a separate resource that appears in a resource group. The same user-assigned identity can be assigned to multiple resources. This is useful if you want all your deployment slots on an app service to have the same identity to reduce the number of role assignments.

Use Managed Identities with Azure Storage Blobs

To start using an Azure App Service managed identities, create a new project and install a few packages.

Microsoft's newest packages make it easy to do this with minimal code. Run the following commands in the command prompt:

1
2
3
4
5
6
mkdir PLStorageManagedIdentity
cd PLStorageManagedIdentity
dotnet new mvc
dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Azure
sh

The code above creates a new MVC project and installs Azure.Storage.Blobs, Azure.Identity, and Microsoft.Extensions.Azure. Azure.Identity is a generic package that allows you to fetch tokens to authorize with differences protected Azure resources.

Then update your Startup.cs file to register Blob Services for dependency injection.

1
2
3
4
5
6
7
8
9
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersWithViews();
  services.AddAzureClients(cfg =>
  {
     cfg.AddBlobServiceClient(Configuration.GetSection("Blobs")).WithCredential(new Azure.Identity.DefaultAzureCredential());
  });
}
csharp

The code above will look at your configuration, such as AppSettings.json, to determine which Azure Storage Blob account to connect. If it is run on your development machine, it will use Visual Studio or Azure CLI to attempt to authenticate. When run in the Azure App Service, it will use the user-assigned identity discussed above.

To configure the Azure Storage Blob account, you can update AppSettings.json to the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Blobs": {
    "ServiceUri": "https://xxxxxxxx.blob.core.windows.net/"
  }
}
json

Note that no secrets like connection strings or passwords are required. You will also need to make sure your identities have the correct roles for the Azure Storage Blob account. If you need read and write access, assign the Storage Blob Data Contributor built-in role.

Finally, to use the newly registered blob services, update HomeController.cs with the following:

1
2
3
4
5
6
7
8
9
10
11
12
public HomeController(ILogger<HomeController> logger, BlobServiceClient blobServiceClient)
{
    _logger = logger;
    _blobContainerClient = blobServiceClient.GetBlobContainerClient("artifacts");
}
private readonly BlobContainerClient _blobContainerClient;

public IActionResult Blob()
{
    var result = new { exists = _blobContainerClient.Exists() };
    return Json(result);
}
csharp

With your roles set up correctly, you can now read and write to the blob container. Queue storage and file storage services can be also be authenticated in a similar way.

Connect to Multiple Storage Accounts

So far, the code above only connects to one storage account. The Azure SDK also makes it easy to connect to multiple storage accounts.

1
2
3
4
5
services.AddAzureClients(cfg =>
{
  cfg.AddBlobServiceClient(Configuration.GetSection("Blobs")).WithCredential(new Azure.Identity.DefaultAzureCredential());
  cfg.AddBlobServiceClient(Configuration.GetSection("Inputs")).WithName("Inputs").WithCredential(new Azure.Identity.DefaultAzureCredential());
});
csharp

You have created a named registration and a default registration. They are configured separately in the AppSettings.json file.

1
2
3
4
5
6
7
8
{
  "Blobs": {
    "ServiceUri": "https://xxxxxxxx.blob.core.windows.net/"
  },
  "Inputs": {
    "ServiceUri": "https://yyyyyyyy.blob.core.windows.net/"
  }
}

There are two separate ServiceUris set. There are two configuration sections, one called Blobs and one called Inputs.

To access them in the rest of your code, you need to use the IAzureClientFactory.

1
2
3
4
5
6
7
8
9
public HomeController(
    ILogger<HomeController> logger,
    IAzureClientFactory<BlobServiceClient> clientFactory,
    BlobServiceClient blobServiceClient)
{
    _logger = logger;
    var client2 = clientFactory.CreateClient("Inputs");
    _blobContainerClient = blobServiceClient.GetBlobContainerClient("artifacts");
}
csharp

If you want to access the default Azure Storage Blob Account, you can directly inject BlobServiceClient to the constructor. If you want to access a named registration, you need to inject the IAzureClientFactory<T> and call its CreateClient("Inputs") method. This is similar to using the HttpClientFactory.

Conclusion

Microsoft Azure has a growing list of services that support managed identities for Azure resources. Using this feature can enhance the security of your application since you don't need to manage secrets yourself. To build on these skills, read about How to Define Azure Role-based Access Control (RBAC).

2