Here's a detailed and well-structured StackOverflow post for you to use:
We are working on an Azure-based web application and are encountering persistent authorization issues when attempting to upload files to Azure Blob Storage. Despite trying multiple authentication methods (Managed Identity & SAS tokens), we continue to receive AuthorizationFailure
errors.
We need to allow the frontend (React app) to upload files to Azure Blob Storage, through our backend API securely.
We enabled System-Assigned Managed Identity for our BackendAPI (Azure App Service) and assigned it the following IAM roles:
Role | Scope |
---|---|
Storage Blob Data Contributor | /subscriptions/{subscriptionId}/resourceGroups/OmegaWrap |
Storage Blob Data Owner | /subscriptions/{subscriptionId}/resourceGroups/OmegaWrap/providers/Microsoft.Storage/storageAccounts/omegawrapstorage |
Here is the updated Backend Code section including the ManagedIdentityCredential
implementation as well as the reference to the Microsoft documentation source you originally found:
We initially followed Microsoft's official documentation (link) and attempted two different credential approaches:
The first approach uses DefaultAzureCredential
, which automatically picks the best available authentication method based on the environment.
static async Task<BlobContainerClient> GetBlobContainerClientAsync(string storageAccount, string containerName)
{
var credential = new DefaultAzureCredential();
var blobServiceClient = new BlobServiceClient(new Uri($"https://{storageAccount}.blob.core.windows.net"), credential);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
if (!await blobContainerClient.ExistsAsync())
{
await blobContainerClient.CreateIfNotExistsAsync(PublicAccessType.None);
}
return blobContainerClient;
}
Since DefaultAzureCredential
tries multiple methods (e.g., environment variables, CLI login, managed identity, etc.), we also tried directly using ManagedIdentityCredential
, which explicitly targets Managed Identity authentication.
static async Task<BlobContainerClient> GetBlobContainerClientAsync(string storageAccount, string containerName)
{
var credential = new ManagedIdentityCredential(); // Explicitly using Managed Identity
var blobServiceClient = new BlobServiceClient(new Uri($"https://{storageAccount}.blob.core.windows.net"), credential);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
if (!await blobContainerClient.ExistsAsync())
{
await blobContainerClient.CreateIfNotExistsAsync(PublicAccessType.None);
}
return blobContainerClient;
}
We followed Microsoft's documentation on authenticating with System-Assigned Managed Identity:
🔗 Microsoft Docs - System-Assigned Managed Identity in .NET
Despite implementing both approaches, we continue getting the same AuthorizationFailure (403)
error when our backend tries to authenticate and upload files to Azure Blob Storage.
❌ Error Message (403 - AuthorizationFailure)
<Error>
<Code>AuthorizationFailure</Code>
<Message>This request is not authorized to perform this operation.</Message>
</Error>
Even after waiting hours for IAM role propagation, the error persists.
curl
:curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?resource=https://storage.azure.com&api-version=2019-08-01"
After struggling with Managed Identity, we generated an SAS token and attempted to authenticate the backend this way.
az storage container generate-sas \
--account-name omegawrapstorage \
--name uploads \
--permissions acdlrw \
--expiry 2025-03-01T00:00:00Z \
--output tsv
The generated SAS token was then used in the backend:
var sasUri = $"https://{storageAccount}.blob.core.windows.net/{containerName}?{sasToken}";
var blobServiceClient = new BlobServiceClient(new Uri(sasUri));
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
❌ Same AuthorizationFailure
(403) error persists.
We continue getting the following errors regardless of the authentication method:
<Error>
<Code>AuthorizationFailure</Code>
<Message>This request is not authorized to perform this operation.</Message>
</Error>
<Error>
<Code>AuthorizationFailure</Code>
<Message>This request is not authorized to perform this operation.</Message>
</Error>
AuthorizationFailure
despite having full permissions?jwt.ms
.DefaultAzureCredential
configurations, ensuring it's using Managed Identity.At this point, we've exhausted all known approaches to authenticate properly with Azure Blob Storage. If anyone has successfully implemented secure backend authentication for Blob Storage in an Azure App Service environment, we would really appreciate your insights and recommendations.
Any help is greatly appreciated! 🚀
We are using User-Assigned Managed Identities to connect to azure resources (SQL, ACS, Keyvault, and BlobStorage) I prefer user-assigned so if I need to tear down the app service I don't have to rebuild the identity that has access, and can be reused if needed.
Our Managed Identity has been granted Storage Blob Data Contributor
via RBAC to our storage account, which I can see you already have with a system-assigned MI.
Is your storage account configured to be private? It's been a while for me, but I think we had the same problems when we created a storage account that we made private.
The only way we got it to work was either via a connection string (which we also did not want to use) or by configuring with vnets and a private link.
Just to give you a quick and dirty on how we set this up:
You might have to also set up a private DNS record. We had to do this because we did things a little differently than this, but my understanding is that the private link creation wizard should set up the NIC and the dns records you need so the public dns will route to the private link record tied to the IP in the subnet.