Getting error when copying file from one container to another container in Azure Storage using .Net client library

huangapple go评论66阅读模式
英文:

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 = &quot;targetContainer&quot;;  
var targetStorageAccount = &quot;targetStorage&quot;;
var targetUrlurl2 = @&quot;https://&quot; + targetStorageAccount + &quot;.blob.core.windows.net&quot;;
  var targetServiceClient = new BlobServiceClient(
           new Uri(targetUrlurl2),
       new DefaultAzureCredential());



        var stageStorageAccount = &quot;sourceStorage&quot;; 
        var stageContainer = &quot;sourceContainer&quot;;

        var stageUrl = @&quot;https://&quot; + stageStorageAccount + &quot;.blob.core.windows.net&quot;;
        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 = &quot;b&quot;,
    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();

huangapple
  • 本文由 发表于 2023年6月13日 13:26:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定