【问题标题】:Getting Error while Creating SAS Token for Azure Storage Blob with MSI使用 MSI 为 Azure 存储 Blob 创建 SAS 令牌时出错
【发布时间】:2021-05-05 09:20:35
【问题描述】:

我正在尝试为存储 blob 创建一个 SAS 令牌。我使用使用 MSI(托管服务标识)创建的 StorageCredentials 来创建 CloudBlobClient。创建 SAS 时,我收到“除非使用帐户密钥凭据,否则无法创建共享访问签名”。是否支持带有 MSI 的 SAS?

var container = blobClient.GetContainerReference(containerName);
var blockBlob = container.GetBlockBlobReference(snapname);
var sas = string.Concat(blockBlob.Uri.ToString(), blockBlob.GetSharedAccessSignature(sasConstraints));

这就是我创建 StorageCredentials 的方式:

tokenCallback = CreateMsiCallback();
var initToken = await tokenCallback(audience);
return new StorageCredentials(
  new TokenCredential(initToken, async (state, token) =>
  {
    var accessToken = await _tokenCallback(audience);

    return new NewTokenAndFrequency(accessToken, TimeSpan.FromMinutes(1));
  }, null, TimeSpan.FromMinutes(1))
);

要创建令牌回调,我使用 HttpClient

public Func<string, Task<string>> CreateMsiCallback()
{
  var handler = new HttpClientHandler
  {
     ServerCertificateCustomValidationCallback =
         (httpRequestMessage, cert, certChain, policyErrors) =>
         {
             if (policyErrors == SslPolicyErrors.None)
             {
                 return true;
             }

             return 0 == string.Compare(cert.GetCertHashString(), FabricThumbprint, StringComparison.OrdinalIgnoreCase);
        }
  };

     var client = new HttpClient(handler)
     {
         DefaultRequestHeaders =
         {
            {"secret", FabricAuthenticationCode }
         }
     };

     return async (resource) =>
     {
            var requestUri = $"{FabricMsiEndpoint}?api-version={FabricApiVersion}&resource={HttpUtility.UrlEncode(resource)}";
            var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUri);
            var response = await client.SendAsync(requestMessage);
            response.EnsureSuccessStatusCode();
            var tokenResponseString = await response.Content.ReadAsStringAsync();
            var tokenResponseObject =
                JsonConvert.DeserializeObject<ManagedIdentityTokenResponse>(tokenResponseString);
            
            return tokenResponseObject.AccessToken;
        };
    }
}

【问题讨论】:

  • 既然使用了MSI,为什么不使用Azure ad auth来访问azure blob?
  • 我们有一个框架可以连接到不同的环境,其中一些是基于 Service Fabric 的,一些不是,还有一些用于测试和本地机器开发。所以我们需要一个通用的 API。

标签: azure azure-blob-storage azure-managed-identity


【解决方案1】:

根据此Github issue,您需要将存储数据角色分配给您的 MSI 以生成 SAS 令牌。从这个线程:

错误是因为您的 oauth 帐户没有权限 生成用户委托密钥。使用 Oauth 存储上下文获取 SAS (New-AzStorageContext -UseConnectedAuth),我们需要先生成 来自服务器的 UserDelegationKey,然后使用密钥生成 SAS 令牌。

请检查您是否为 Oauth 登录用户分配了正确的角色 (使用 Connect-AzAccount)。至少喜欢以下 4 个角色之一 在特定的存储帐户上:

  • 存储 Blob 数据所有者
  • 存储 Blob 数据贡献者
  • 存储 Blob 数据读取器
  • 存储 Blob 委托人

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 2022-01-17
    • 2022-07-19
    • 2019-12-05
    • 2021-11-20
    • 2021-02-12
    • 1970-01-01
    相关资源
    最近更新 更多