Azure Function App 无法使用存储帐户进行身份验证,除非重新启动

问题描述 投票:0回答:1

我正在使用持久功能编排来执行 3 项任务(活动)。其中一项任务将 blob 从一个存储帐户复制到另一个存储帐户。我通过以下方式实例化源和目标 BlobServiceClient 对象:

TokenCredential creds = new DefaultAzureCredential();
_sourceServiceClient = new BlobServiceClient(new Uri($"https://{_sourceStorageAcctName}.blob.core.windows.net"), creds);
_targetServiceClient = new BlobServiceClient(_targetStorageAcctConnStr);

// default user delegation key expiration to 1 hour
_userDelegationKey = _sourceServiceClient.GetUserDelegationKey(null, DateTimeOffset.UtcNow.AddHours(1));

考虑到要复制的 blob 数量,完成作业的时间不应超过 10 分钟,因此我为用户委托密钥设置了 1 小时的到期日期。一旦我有了要复制的 blob 列表,我就会循环遍历它并生成一个具有读取权限且过期时间为 5 分钟的 SAS,然后调用:

targetBlobClient.StartCopyFromUri(sourceBlobSASURI)

对列表中的每个斑点重复此操作。我的 Azure 帐户和函数的托管标识已添加到源存储帐户中的“存储 Blob 数据贡献者”角色。在 Visual Studio 中进行本地测试效果很好。当我将该函数部署到 Azure 并手动运行它时,它工作正常。

然后,我安排该函数每天运行,但现在该函数无法通过存储帐户进行身份验证,并显示以下消息:

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:cf03b2fa-001e-0028-7aec-6e22a1000000
Time:2024-03-05T11:00:17.9880230Z
Status: 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
ErrorCode: CannotVerifyCopySource

Content:
<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>CannotVerifyCopySource</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:cf03b2fa-001e-0028-7aec-6e22a1000000
Time:2024-03-05T11:00:17.9880230Z</Message></Error>

Headers:
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: cf03b2fa-001e-0028-7aec-6e22a1000000
x-ms-client-request-id: d6e94e13-cb3e-44e8-a874-df40a9a9faa6
x-ms-version: 2023-08-03
x-ms-error-code: CannotVerifyCopySource
Date: Tue, 05 Mar 2024 11:00:17 GMT
Content-Length: 322
Content-Type: application/xml
\r
\r
   at Azure.Storage.Blobs.BlobRestClient.StartCopyFromURL(String copySource, Nullable`1 timeout, IDictionary`2 metadata, Nullable`1 tier, Nullable`1 rehydratePriority, Nullable`1 sourceIfModifiedSince, Nullable`1 sourceIfUnmodifiedSince, String sourceIfMatch, String sourceIfNoneMatch, String sourceIfTags, Nullable`1 ifModifiedSince, Nullable`1 ifUnmodifiedSince, String ifMatch, String ifNoneMatch, String ifTags, String leaseId, String blobTagsString, Nullable`1 sealBlob, Nullable`1 immutabilityPolicyExpiry, Nullable`1 immutabilityPolicyMode, Nullable`1 legalHold, CancellationToken cancellationToken)
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.StartCopyFromUriInternal(Uri source, IDictionary`2 metadata, IDictionary`2 tags, Nullable`1 accessTier, BlobRequestConditions sourceConditions, BlobRequestConditions destinationConditions, Nullable`1 rehydratePriority, Nullable`1 sealBlob, BlobImmutabilityPolicy destinationImmutabilityPolicy, Nullable`1 legalHold, Boolean async, CancellationToken cancellationToken)
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.StartCopyFromUri(Uri source, IDictionary`2 metadata, Nullable`1 accessTier, BlobRequestConditions sourceConditions, BlobRequestConditions destinationConditions, Nullable`1 rehydratePriority, CancellationToken cancellationToken)
...

即使在看到失败后手动运行它,它也会失败并显示相同的消息。但是,如果我重新启动功能应用程序然后再次运行它,它就可以正常工作。我正在努力弄清楚为什么只需重新启动功能应用程序就能解决问题?然而,这不是永久修复,因为最终计划的执行将再次遇到错误,通常是在 24 小时内。

我正在使用“进程中”模型,想知道这是否与此有关。非常感谢对此行为的任何见解。

azure-functions azure-blob-storage azure-storage-account shared-access-signatures
1个回答
0
投票

我在这里找到了这个问题。包含我的函数的类被声明为静态,包括实例化我的 _sourceServiceClient_targetServiceClient 对象的属性。因此,第一次执行时一切正常,但在后续执行中,它会重用静态对象以及第一次执行期间分配的值。因此,1 小时后,用户委托密钥过期,导致我发布的错误。

通过删除类及其属性的静态属性,每次执行都会生成一个新的用户委托密钥,从而解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.