【问题标题】:Azure Blob Storage "Authorization Permission Mismatch" error for get request with AD token使用 AD 令牌获取请求的 Azure Blob 存储“授权权限不匹配”错误
【发布时间】:2021-05-12 02:05:01
【问题描述】:

我正在构建一个 Angular 6 应用程序,它将能够在 Azure Blob 存储上进行 CRUD 操作。但是,我使用邮递员测试请求,然后在应用程序中实现它们并复制粘贴我从 Angular 获得的用于该资源的令牌。

当尝试读取存储在存储中的文件以进行测试时,我得到:<Code>AuthorizationPermissionMismatch</Code> <Message>This request is not authorized to perform this operation using this permission.

  • 全部在生产环境中(尽管正在开发中)
  • 通过 Oauth 专门为存储资源获取的令牌
  • Postman 的令牌策略为“bearer”
  • 应用程序已授予“Azure 存储”委派权限。
  • 应用程序和我获取令牌的帐户都添加为 azure 访问控制 IAM 中的“所有者”
  • 我的 IP 已添加到 Blob 存储的 CORS 设置中。
  • StorageV2(通用 v2) - 标准 - 热
  • x-ms-version 使用的标头是:2018-03-28,因为这是我能找到的最新版本,而且我刚刚创建了存储帐户。

【问题讨论】:

  • 所以用户需要对 blob 存储的 IAM 权限???
  • @Thomas 我不知道伙计,我只是添加它以确保这不是原因。

标签: azure azure-active-directory azure-blob-storage


【解决方案1】:

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

  • 存储 Blob 数据贡献者
  • 存储队列数据贡献者

【讨论】:

  • Link 到文档
  • 对我来说它只有在添加角色“存储队列数据贡献者”后才有效
  • 根据您执行的操作,您可能需要“存储 Blob 数据所有者”而不是贡献者。但似乎作为资源的所有者并没有覆盖这个
  • +1 到@user2526641,添加“Storage Blob Data Contributor”和“Storage Queue Data Contributor”后工作
  • 如果您不确定,什么在从 DevOps 管道部署时需要在 IAM 中添加:它应该是服务主体名称(AAD 应用程序名称)您的 DevOps 服务连接。
【解决方案2】:

确保使用 Storage Blob Data Contributor 而不是 Storage Account Contributor,后者仅用于管理实际存储帐户而不是其中的数据。

【讨论】:

    【解决方案3】:

    我刚刚解决了这个问题,方法是将 GetAccessTokenAsync 方法中请求的资源从“https://storage.azure.com”更改为我的存储 blob 的 url,就像在这个 sn-p 中一样:

        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/

    【讨论】:

      【解决方案4】:

      请注意,如果您想在订阅级别应用“STORAGE BLOB DATA XXXX”角色,如果您的订阅具有 Azure DataBricks 命名空间,则该角色将不起作用:

      如果您的订阅包含 Azure DataBricks 命名空间,则在订阅范围内分配的角色将被阻止授予对 blob 和队列数据的访问权限。

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

      【讨论】:

        【解决方案5】:

        确保在命令末尾添加/Y

        【讨论】:

          【解决方案6】:

          使用以下内容通过 Azure AD 连接到 Blob 存储: 这是使用 SDK V11 的代码,因为 V12 仍然存在多个 AD 帐户的问题 看到这个问题 https://github.com/Azure/azure-sdk-for-net/issues/8658 进一步阅读 V12 和 V11 SDK

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

          https://docs.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;
                      }
                  }
          

          【讨论】:

            猜你喜欢
            • 2021-06-06
            • 2016-11-30
            • 2021-08-15
            • 2021-08-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-05
            • 1970-01-01
            相关资源
            最近更新 更多