【问题标题】:Azure Identity: Trying to get GetUserDelegationKey to work with an application Service PrincipalAzure 标识:尝试让 GetUserDelegationKey 与应用程序服务主体一起使用
【发布时间】:2020-05-01 00:45:01
【问题描述】:

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

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

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

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

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

我过得很糟糕。

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

所有这些都记录在here at 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
        }
    }
}

尽管这个程序再简单不过了,但每次调用 GetUserDelegationKey 时都会出现 XML 错误而失败

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 节点?

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

【问题讨论】:

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


    【解决方案1】:

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

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

    希望这会有所帮助。

    【讨论】:

    • 确实如此;我的服务主体是 owner,但还不够好 - 添加 Storage Blob Data Contributor 角色就可以了。谢谢。
    • 唉,委托的密钥只能使用 7 天 - 请求更长的时间会产生与以前相同的 XML 节点错误。现在要寻找不同的方法...
    • 可以在本地运行这段代码吗?还是只有在 Azure 上部署时才有效?
    猜你喜欢
    • 1970-01-01
    • 2021-08-08
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多