英文:
Getting error when copying file from one container to another container in Azure Storage using .Net client library
问题
I am trying to copy a file from one storage account container to another storage account container. Both accounts are public. I am using Microsoft Managed account (Role based access account) and I am the owner. From my machine as an admin, I am able to perform upload, download, and get the list from both containers. But when I perform a copy, I get the below error.
var targetContainer = "targetContainer";
var targetStorageAccount = "targetStorage";
var targetUrlurl2 = @"https://" + targetStorageAccount + ".blob.core.windows.net";
var targetServiceClient = new BlobServiceClient(
new Uri(targetUrlurl2),
new DefaultAzureCredential());
var stageStorageAccount = "sourceStorage";
var stageContainer = "sourceContainer";
var stageUrl = @"https://" + stageStorageAccount + ".blob.core.windows.net";
var stageServiceClient = new BlobServiceClient(
new Uri(stageUrl),
new DefaultAzureCredential());
BlobContainerClient stageContainerClient = stageServiceClient.GetBlobContainerClient(stageContainer);
var list = stageContainerClient.GetBlobs();
BlobContainerClient targetContainerClient = targetServiceClient.GetBlobContainerClient(targetContainer);
BlobClient sourceBlobClient = stageContainerClient.GetBlobClient(fileName);
BlobClient targetBlobClient = targetContainerClient.GetBlobClient(fileName);
var result = targetBlobClient.StartCopyFromUri(sourceBlobClient.Uri);
Error:
Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
RequestId: c9a58588-301e-0062-1686-9d067c000000
Time: 2023-06-12T23:32:17.2971373Z
Status: 401 (Server failed to authenticate the request. Please refer to the information in the www-authenticate header.)
ErrorCode: CannotVerifyCopySource
CannotVerifyCopySource
<Message>Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
RequestId: c9a58588-301e-0062-1686-9d067c000000
Time: 2023-06-12T23:32:17.2971373Z</Message></Error>
Headers:
x-ms-request-id: c9a58588-301e-0062-1686-9d067c000000
x-ms-client-request-id: 4ee3654d-3c1f-44d2-bd87-66297ef299e1
x-ms-version: 2022-11-02
x-ms-error-code: CannotVerifyCopySource
Content-Length: 297
Content-Type: application/xml
Date: Mon, 12 Jun 2023 23:32:17 GMT
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
英文:
I am trying to copy a file from one storage account container to another storage account container. Both accounts are public. I am using Microsoft Managed account (Role based access accoount)and I am the owner.
From my machine as an admin. I am able to perform upload, download and get the list from both container. but when I perform copy. I get the below error. See the below code and then the error.
var targetContainer = "targetContainer";
var targetStorageAccount = "targetStorage";
var targetUrlurl2 = @"https://" + targetStorageAccount + ".blob.core.windows.net";
var targetServiceClient = new BlobServiceClient(
new Uri(targetUrlurl2),
new DefaultAzureCredential());
var stageStorageAccount = "sourceStorage";
var stageContainer = "sourceContainer";
var stageUrl = @"https://" + stageStorageAccount + ".blob.core.windows.net";
var stageServiceClient = new BlobServiceClient(
new Uri(stageUrl),
new DefaultAzureCredential());
BlobContainerClient stageContainerClient = stageServiceClient.GetBlobContainerClient(stageContainer);
var list = stageContainerClient.GetBlobs();
BlobContainerClient targetContainerClient = targetServiceClient.GetBlobContainerClient(targetContainer);
BlobClient sourceBlobClient = stageContainerClient.GetBlobClient(fileName);
BlobClient targetBlobClient = targetContainerClient.GetBlobClient(fileName);
var result = targetBlobClient.StartCopyFromUri(sourceBlobClient.Uri);
Error
Server failed to authenticate the request. Please refer to the information in the www-
authenticate header.
RequestId:c9a58588-301e-0062-1686-9d067c000000
Time:2023-06-12T23:32:17.2971373Z
Status: 401 (Server failed to authenticate the request. Please refer to the information in
the www-authenticate header.)
ErrorCode: CannotVerifyCopySource
CannotVerifyCopySource
<Message>Server failed to authenticate the request. Please refer to the information in the
www-authenticate header.
RequestId:c9a58588-301e-0062-1686-9d067c000000
Time:2023-06-12T23:32:17.2971373Z</Message></Error>
Headers:
x-ms-request-id: c9a58588-301e-0062-1686-9d067c000000
x-ms-client-request-id: 4ee3654d-3c1f-44d2-bd87-66297ef299e1
x-ms-version: 2022-11-02
x-ms-error-code: CannotVerifyCopySource
Content-Length: 297
Content-Type: application/xml
Date: Mon, 12 Jun 2023 23:32:17 GMT
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
答案1
得分: 1
为了解决此问题,请使用具有至少“读取”权限的 SAS URL 用于源 blob。
为使跨存储账户的复制操作生效,源 blob 必须以某种方式公开访问(SAS URL 是一种方法),以便在执行复制操作时可以被存储服务读取。
更新
请查看下面的代码,了解如何在源 blob 上创建用户委托 SAS。
DateTimeOffset expiryTime = DateTimeOffset.UtcNow.AddMinutes(5);
var userDelegationKey = await stageServiceClient.GetUserDelegationKeyAsync(null, expiryTime, CancellationToken.None);
var sasBuilder = new BlobSasBuilder()
{
BlobContainerName = containerName,
BlobName = blobName,
Resource = "b",
ExpiresOn = linkExpiry
};
sasBuilder.SetPermissions(BlobSasPermissions.Read);
var blobClient = stageContainerClient.GetBlobClient(fileName);
var blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
{
Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
stageServiceClient.AccountName)
};
return blobUriBuilder.ToUri();
英文:
To fix this issue, please use a SAS URL with at least read
permission for the source blob.
For copy operation across storage accounts to work, source blob must be publicly accessible somehow (SAS URL is one way to do it) so that it can be read by storage service when performing copy operation.
UPDATE
Please take a look at the code below to see how you can create a User Delegation SAS on the source blob.
DateTimeOffset expiryTime = DateTimeOffset.UtcNow.AddMinutes(5);
var userDelegationKey = await stageServiceClient.GetUserDelegationKeyAsync(null, expiryTime, CancellationToken.None);
var sasBuilder = new BlobSasBuilder()
{
BlobContainerName = containerName,
BlobName = blobName,
Resource = "b",
ExpiresOn = linkExpiry
};
sasBuilder.SetPermissions(BlobSasPermissions.Read);
var blobClient = stageContainerClient.GetBlobClient(fileName);
var blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
{
Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
stageServiceClient.AccountName)
};
return blobUriBuilder.ToUri();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论