使用AD令牌进行GET请求时,Azure Blob Storage出现“授权权限不匹配”错误

88
我正在构建一个Angular 6应用程序,可以在Azure Blob Storage上进行CRUD操作。但在将请求实现到应用程序中之前,我使用Postman进行测试,并复制从Angular获取的令牌以访问资源。
当尝试读取我在存储中用于测试的文件时,出现以下错误: AuthorizationPermissionMismatch 使用此权限执行此操作的请求未获授权。
  • 所有内容都在生产环境中(尽管正在开发)
  • 特定于存储资源通过Oauth获取的令牌
  • Postman将令牌策略设置为"bearer"
  • 已授予应用程序“Azure Storage”委派权限。
  • 我正在获取令牌的应用程序和帐户均被添加为Azure访问控制IAM中的“所有者”
  • 我的IP地址已添加到Blob Storage的CORS设置中。
  • StorageV2(通用目的v2) - 标准 - 热
  • 使用的x-ms-version标头是: 2018-03-28,因为这是我能找到的最新版本,而且我刚刚创建了存储帐户。

所以用户需要在 Blob 存储上拥有 IAM 权限吗? - Thomas
1
@Thomas 我不知道啊,伙计,我只是为了确保这不是原因而添加的。 - SebastianG
1
对于那些遇到类似问题并且答案没有帮助的人,可以尝试在 Azure 门户侧边栏中为您的存储帐户使用“诊断和解决问题”工具。它将帮助您查看日志以了解发生了什么。通过它,我发现我正在使用与我想象中不同的服务主体。 - MakotoE
9个回答

205

我发现将应用程序和账户添加为所有者是不够的。我会进入你的存储账户 > IAM > 添加角色分配,并为这种类型的请求添加特殊权限:

  • 存储 Blob 数据参与者
  • 存储队列数据参与者

8
这是文档的链接:https://learn.microsoft.com/zh-cn/azure/storage/common/storage-auth-aad-app - nldev
11
只有在添加了“存储队列数据贡献者”角色后,它才对我起作用。 - user2526641
3
根据您的操作,您可能需要“存储 Blob 数据所有者”而不是贡献者。但是似乎拥有资源的所有者身份并不能覆盖此要求。 - Liam
1
如果您不确定在从DevOps管道部署时需要在IAM中添加什么,那么应该是您的DevOps服务连接的服务主体名称(AAD应用程序名称)。 - jetnet
1
微软在从Microsoft.WindowsAzure.Storage迁移到Microsoft.Azure.Storage,再到Azure.Storage时真的搞砸了。就像左手不知道右手在Redmond那边在干什么一样!无论如何,这帮助我解决了迁移到Azure.Storage后为什么我的Azure队列无法工作的问题! - ScottyMacDev
显示剩余6条评论

13

请确保使用“存储 Blob 数据参与者”而不是“存储帐户参与者”,因为后者仅用于管理实际的存储帐户而不是其中的数据。


4

4

我刚刚通过更改GetAccessTokenAsync方法中请求的资源,从“https://storage.azure.com”更改为我的存储Blob的URL来解决了这个问题,以下是示例:

    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;
    }

AzureStorageContainerUrl被设置为https://xxxxxxxxx.blob.core.windows.net/


2
请确保在命令的末尾添加 /Y

1
只是添加了JimJohnBobJohnes回答的解决方案的可视化呈现。
1. 转到存储帐户 > IAM > 添加角色分配。 2. 在“添加角色分配”中,选择以下两个角色: - 存储 Blob 数据参与者 - 存储队列数据参与者
3. 将其分配给您的帐户。 4. 这些应该在您的存储帐户上反映出来(绿色高亮显示)。

enter image description here


1

使用以下方法连接Azure AD到Blob存储:这段代码使用SDK V11,因为V12在多个AD账户方面仍然存在问题。请参见此问题https://github.com/Azure/azure-sdk-for-net/issues/8658以了解有关V12和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;
            }
        }

0

我在使用 Azure Pipeline(TerraformTaskV3@3)时遇到了 Terraform 的问题,出现了以下错误

 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" 

Storage Blob Data Contributor角色添加到用于连接AzureDevops到Azure订阅的服务主体中,可以解决该问题。

相关问题:错误:无法获取现有工作区:containers.Client#ListBlobs:


-1
我在Azure Pipeline任务AzureFileCopy@5中遇到了类似的问题。
为了解决这个问题,我进入Azure > 存储帐户 > 访问控制(IAM),并给已经拥有Contributor角色的应用程序添加了Storage Blob Data Contributor角色。
这个角色可以在资源或订阅级别上添加(文档)。

Capture of the status once the roles have been added in Azure Pipeline


已经有类似的答案发布了,并且已被作者接受。如果答案提供了额外的信息,请编辑答案。 - ranka47

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接