在本地生成用户委托 SAS 令牌 运行

Generate user delegation SAS token running locally

我正在根据此 [文档][1] 创建解决方案。我让它几乎按我想要的方式工作,但它只有在部署到 Azure 时才能工作。应用服务已配置托管标识并分配了 Storage Blob Data Contributor 角色。有什么方法可以在我的本地机器上使它成为 运行 吗?目前我需要将代码从 VS 发布到 Azure,然后使用远程调试来验证它是如何工作的。 这是有问题的行:

userDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
   DateTimeOffset.UtcNow.AddDays(7));

我遇到异常:

Status: 400 (The value for one of the XML nodes is not in the correct format.)
ErrorCode: InvalidXmlNodeValue

我使用 DefaultAzureCredentials 并且在调试中我看到它有 3 个不同的来源。首先是 EnvironmentCredential(然后是 ManagedIdentityCredentialSharedTokenCacheCredential)。所以我尝试在 Azure AD 中注册应用程序并配置这 3 个环境变量,但它没有帮助。也许我需要为此应用添加一些特定权限?

"AZURE_CLIENT_ID": "",
"AZURE_CLIENT_SECRET": "",
"AZURE_TENANT_ID": ""

或者这可能以某种方式适用于我在 Azure 中的帐户?如果我也被分配 Storage Blob Data Contributor 角色?

编辑: 我用 Fiddler 捕获了请求和响应

要求:

POST https://myaccount.blob.core.windows.net/?restype=service&comp=userdelegationkey HTTP/1.1
Host: myaccount.blob.core.windows.net
x-ms-version: 2019-07-07
x-ms-client-request-id: 23071825-dcf0-4803-a8a9-c44ec38695d5
x-ms-return-client-request-id: true
User-Agent: azsdk-net-Storage.Blobs/12.4.4 (.NET Core 3.1.2; Microsoft Windows 10.0.16299)
Authorization: Bearer Hidden
traceparent: 00-7e23f80250325742853c846211a83d02-6739d4cbc8ef0a46-00
Content-Type: application/xml
Content-Length: 91

<KeyInfo><Start>2020-07-08T06:02:35Z</Start><Expiry>2020-07-15T06:17:35Z</Expiry></KeyInfo>

响应:

HTTP/1.1 400 The value for one of the XML nodes is not in the correct format.
Content-Length: 348
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: ba2fe641-f01e-0065-3eef-54acae000000
x-ms-client-request-id: 23071825-dcf0-4803-a8a9-c44ec38695d5
x-ms-version: 2019-07-07
x-ms-error-code: InvalidXmlNodeValue
Date: Wed, 08 Jul 2020 06:16:14 GMT

<?xml version="1.0" encoding="utf-8"?><Error><Code>InvalidXmlNodeValue</Code><Message>The value for one of the XML nodes is not in the correct format.
RequestId:ba2fe641-f01e-0065-3eef-54acae000000
Time:2020-07-08T06:16:15.7553428Z</Message><XmlNodeName>2020-07-15T06:17:35Z</XmlNodeName><XmlNodeValue>2020-07-15T06:17:35Z</XmlNodeValue></Error>

编辑 2: 它在@JimXu 的帮助下工作。此外,我能够使其与在 Visual Studio 中配置的 Azure 帐户一起使用,因此我可以删除为此目的在 Azure AD 中创建的应用程序注册。 [1]: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet#example-get-a-user-delegation-sas

如果要获取Azure存储账户User Delegation Key,需要将Storage Blob Data ContributorStorage Blob Data OwnerStorage Blob Delegator分配给AD应用程序或账户。详情请参考document

另外请注意,我们在获取Azure存储账户User Delegation Key时,需要提供过期时间。其值必须是当前时间 7 天内的有效日期和时间。详情请参考here.

例如

string accountName = "jimtestdiag417";

            string blobEndpoint = $"https://{accountName}.blob.core.windows.net/";
            

            // Create a new Blob service client with Azure AD credentials.  
            BlobServiceClient blobClient = new BlobServiceClient(new Uri(blobEndpoint),
                                                                    new DefaultAzureCredential();

            // Get a user delegation key for the Blob service that's valid for seven days.
            // to avoid clock skew between the requesting pc and azure servers, please set expire time in future six days
            UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                                DateTimeOffset.UtcNow.AddDays(6));

            // Read the key's properties.
            Console.WriteLine("User delegation key properties:");
            Console.WriteLine("Key signed start: {0}", key.SignedStartsOn);
            Console.WriteLine("Key signed expiry: {0}", key.SignedExpiresOn);
            Console.WriteLine("Key signed object ID: {0}", key.SignedObjectId);
            Console.WriteLine("Key signed tenant ID: {0}", key.SignedTenantId);
            Console.WriteLine("Key signed service: {0}", key.SignedService);
            Console.WriteLine("Key signed version: {0}", key.SignedVersion);
            Console.WriteLine();