首页 > 解决方案 > Azure Identity:尝试让 GetUserDelegationKey 与应用程序服务主体一起使用

问题描述

当我询问的方法GetUserDelegationKey在 SO 上产生零搜索结果时,这不是一个好兆头。祝你好运,我。

我有一个 C# 控制台应用程序 .Net framework 4.8,使用 Azure.Storage.Blobs 和 Azure.Identity 将在客户服务器上运行并访问 Azure blob 存储来保存一些东西。我用图书馆做所有这些,而不是滚动我自己的 REST。用VS2019构建,在Win10上测试。

计划是使用我拥有的单个 Azure 存储帐户,并为每个客户项目创建一个容器,每个客户的凭据只允许他们自己的容器。项目从不相互交谈。

我可以手动在 Azure 门户中设置凭据,但我顽固地尝试在软件中执行此操作,其中一个简单的项目管理应用程序连接为项目应用程序的服务主体(我在 Azure AD 中定义),创建容器,然后创建具有有限生命周期的共享访问签名。

然后将在客户服务器上配置存储帐户名称/容器名称/访问签名。

我过得很糟糕。

注意:这是使用较新的 BlobClient 机制,而不是较旧的 CloudBlob 东西。不知道这是否重要。

这一切都记录在 Microsoft,即使是简单的例子,我也会遇到同样的失败。

using System;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Identity;

namespace Azure.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var serviceClient = new BlobServiceClient(
                new Uri("https://stevestorageacct.blob.core.windows.net"),
                new DefaultAzureCredential(true));  // true=pop up login dlg

/*BOOM*/    UserDelegationKey key = serviceClient.GetUserDelegationKey(
                DateTimeOffset.UtcNow,
                DateTimeOffset.UtcNow.AddDays(30));

            // use the key to create the signatures
        }
    }
}

尽管这个程序再简单不过了,但每次调用都会失败并返回一个 XML 错误GetUserDelegationKey

Unhandled Exception: Azure.RequestFailedException: The value for one of the XML nodes is not in the correct format.
RequestId:c9b7d324-401e-0127-4a4c-1fe6ce000000
Time:2020-05-01T00:06:21.3544489Z
Status: 400 (The value for one of the XML nodes is not in the correct format.)
ErrorCode: InvalidXmlNodeValue

发送的 XML 应该非常简单,我认为只是有效性的开始/结束日期,但我不知道如何检查它,并且http禁止这种调用,所以没有 Wireshark。

当我使用我的应用程序的服务主体时,它也会以同样的方式失败:

        static void Main(string[] args)
        {
            var tokenCredential = new ClientSecretCredential(
                "xxxx-xxxx-xxxx-xxxxx",   // tenant ID
                "yyyy-yyyy-yyyy-yyyyy,    // application ID
                "**************");      // client secret

            var serviceClient = new BlobServiceClient(
                new Uri("https://stevestorageacct.blob.core.windows.net"),
                tokenCredential);

            UserDelegationKey key = serviceClient.GetUserDelegationKey(
                DateTimeOffset.UtcNow,
                DateTimeOffset.UtcNow.AddDays(30));
            // ALSO: boom

我真的很茫然。

我想我可以尝试滚动我自己的 REST 并以这种方式使用它,但感觉没有必要这样做:即使我做错了什么,这种错误感觉就像一个错误。XML 节点?

如果它们更优秀,也可以采用完全不同的方法来解决这个问题,但至少想找出失败的原因。

标签: azureazure-active-directoryazure-storage

解决方案


我对此也有一些问题。首先要尝试的是删除开始时间(传递 null)或将其设置为过去约 15 分钟。这是为了避免请求 pc 和 azure 服务器之间的时钟偏差。

要验证的第二件事是您使用的用户在存储帐户上具有“存储 Blob 数据参与者”角色。最后我必须在存储帐户级别授予它,否则它只是拒绝为我工作。但是,在您的用例中,您可能需要在容器级别授予它以允许您为每个客户端拥有一个容器。

希望这可以帮助。


推荐阅读