SebastianG
SebastianG

Reputation: 9564

Azure Blob Storage "Authorization Permission Mismatch" error for get request with AD token

I am building an Angular 6 application that will be able to make CRUD operation on Azure Blob Storage. I'm however using postman to test requests before implementing them inside the app and copy-pasting the token that I get from Angular for that resource.

When trying to read a file that I have inside the storage for test purposes, I'm getting: <Code>AuthorizationPermissionMismatch</Code> <Message>This request is not authorized to perform this operation using this permission.

Upvotes: 114

Views: 191941

Answers (9)

Dan
Dan

Reputation: 1571

If you want to copy files from/to a fileshare, then you will need to add the Storage File Data Privileged Contributor permission

Upvotes: 0

Rose G
Rose G

Reputation: 588

Just adding visual presentation the solution that JimJohnBobJohnes answered.

  1. Go to Storage account > IAM > Add role assignment.
  2. In 'Add Role Assignment', select these two roles
  • Storage Blob Data Contributor
  • Storage Queue Data Contributor
  1. Assign it to your account.
  2. These should reflect on your storage account (green highlight)

enter image description here

Upvotes: 5

Florin Asavei
Florin Asavei

Reputation: 108

I had this issue when using Terraform on an Azure Pipeline (TerraformTaskV3@3) and got this error

│ Error: Failed to get existing workspaces: containers.Client#ListBlobs: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationPermissionMismatch" 

Adding the Storage Blob Data Contributor role to the service principal used to connect AzureDevops to the Azure Subscription fixed the issue.

Related issue: Error: Failed to get existing workspaces: containers.Client#ListBlobs:

Upvotes: 0

Fjurg
Fjurg

Reputation: 616

Make sure to use Storage Blob Data Contributor and NOT Storage Account Contributor where the latter is only for managing the actual Storage Account and not the data in it.

Upvotes: 17

JimJohnBobJohnes
JimJohnBobJohnes

Reputation: 2606

I found it's not enough for the app and account to be added as owners. I would go into your storage account > IAM > Add role assignment, and add the special permissions for this type of request:

  • Storage Blob Data Contributor
  • Storage Queue Data Contributor

Upvotes: 258

sylr
sylr

Reputation: 153

Be aware that if you want to apply "STORAGE BLOB DATA XXXX" role at the subscription level it will not work if your subscription has Azure DataBricks namespaces:

If your subscription includes an Azure DataBricks namespace, roles assigned at the subscription scope will be blocked from granting access to blob and queue data.

Source: https://learn.microsoft.com/en-us/azure/storage/common/storage-auth-aad-rbac-portal#determine-resource-scope

Upvotes: 4

OmerT
OmerT

Reputation: 11

Used the following to connect using Azure AD to blob storage: This is code uses SDK V11 since V12 still has issues with multi AD accounts See this issue https://github.com/Azure/azure-sdk-for-net/issues/8658 For further reading on V12 and V11 SDK

https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet-legacy

https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet

using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.Storage.Auth;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.Queue;

[Fact]
public async Task TestStreamToContainer()
        {
            try
            {
                var accountName = "YourStorageAccountName";
                var containerName = "YourContainerName";
                var blobName = "File1";
                var provider = new AzureServiceTokenProvider();
                var token = await provider.GetAccessTokenAsync($"https://{accountName}.blob.core.windows.net");
                var tokenCredential = new TokenCredential(token);
                var storageCredentials = new StorageCredentials(tokenCredential);

                string containerEndpoint = $"https://{accountName}.blob.core.windows.net";

                var blobClient = new CloudBlobClient(new Uri(containerEndpoint), storageCredentials);
                var containerClient = blobClient.GetContainerReference(containerName);
                var cloudBlob = containerClient.GetBlockBlobReference(blobName);


                string blobContents = "This is a block blob contents.";
                byte[] byteArray = Encoding.ASCII.GetBytes(blobContents);

                using (MemoryStream stream = new MemoryStream(byteArray))
                {
                    await cloudBlob.UploadFromStreamAsync(stream);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
                throw;
            }
        }

Upvotes: 1

santiago gonzalez
santiago gonzalez

Reputation: 13

Make sure you add the /Y at the end of the command.

Upvotes: -2

Liam
Liam

Reputation: 5476

I've just solved this by changing the resource requested in the GetAccessTokenAsync method from "https://storage.azure.com" to the url of my storage blob as in this snippet:

    public async Task<StorageCredentials> CreateStorageCredentialsAsync()
    {
        var provider = new AzureServiceTokenProvider();
        var token = await provider.GetAccessTokenAsync(AzureStorageContainerUrl);
        var tokenCredential = new TokenCredential(token);
        var storageCredentials = new StorageCredentials(tokenCredential);
        return storageCredentials;
    }

where AzureStorageContainerUrl is set to https://xxxxxxxxx.blob.core.windows.net/

Upvotes: 4

Related Questions