azureauthorizationasp.net-core-webapiazure-blob-storageblob

Azure Blob Storage - This request is not authorized to perform this operation


I've been building an ASP.NET Core Web API that calls Azure Blob Storage to upload and download a file.

Code is very simple so far:

BlobContainerClient containerClient = await _blobServiceClient.CreateBlobContainerAsync(document.Container);
BlobClient blobClient = containerClient.GetBlobClient(document.Name);
return await blobClient.UploadAsync(document.FilePath);

This is supposed to create the container and upload the file. It worked once.

When I attempted to perform a download, I got hit with constants 403s and would not allow me to download the file.

This is the code for downloading, again very simple:

var blobContainer = _blobServiceClient.GetBlobContainerClient("test");
var test = blobContainer.GetBlobClient("testv1");
var test2 = await test.DownloadAsync();

I literally read everything: MS docs regarding authentication/authorization, similar posts from Stackoverflow, changed firewall to only accept requests from my IP address, using my MS Entra ID for authentication, added the suggested roles for the storage account for accessing blobs, out of desperation I tried to disable every possible security rule and made the storage anonymously accessible, and yet when I use Postman to access my API, all I get are http 403 errors.

Can someone please help me understand what am I missing or what am I doing wrong? Because so far none of this is making sense in my head.

Much appreciated.

EDIT: code for authentication in Program.cs:

var uriStr = builder.Configuration["AzureAD:BlobAccountUri"] ?? throw new InvalidOperationException();
var uri = new Uri(uriStr);
TokenCredential credential = null!;

builder.Services.AddAzureClients(clientBuilder =>
{
   clientBuilder.AddBlobServiceClient(uri);

   if (builder.Environment.IsProduction())
   {
      credential = new ManagedIdentityCredential();
   }
   else
   {
     credential = new DefaultAzureCredential();
   }

   clientBuilder.UseCredential(credential);
});

 builder.Services.AddSingleton<BlobServiceClient>(_ => new BlobServiceClient(
uri,
credential));

Since I'm on a Mac and using Rider as my IDE, I'm authenticated via Azure CLI.


Solution

  • Azure Blob Storage - This request is not authorized to perform this operation

    The above error occurs when you don't have the proper permissions or when incorrect authentication is used to access the Azure Storage account.

    I think I managed to fix it? So DefaultAzureCredential() attempts to authenticate using the Environment variables I've setup, for some reason, that didn't work. But if I change to AzureCliCredential, I can upload and download the file.

    The DefaultAzureCredential follows a specific authentication flow and tries multiple credential sources,

    In your environment, you're on a Mac and using Rider, it's possible that the environment variables weren't properly configured or weren't picked up as expected.

    However, AzureCliCredential directly uses the credentials from az login, which explains why switching to it fixed the issue.

    If you want to use DefaultAzureCredential in your code and need to access the Azure CLI credential, you can modify your code as shown below:

    Code:

    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
    {
        ExcludeEnvironmentCredential = true, // Skips env vars since they caused issues
        ExcludeManagedIdentityCredential = true, // No managed identity in local dev
        ExcludeSharedTokenCacheCredential = true, // Not relevant for macOS
        ExcludeInteractiveBrowserCredential = true // Avoids popups
    });
    

    This keeps your production setup intact while ensuring local development works smoothly.

    Reference: DefaultAzureCredential Class (Azure.Identity) - Azure for .NET Developers | Microsoft Learn