1
votes

I'm trying to copy one blob, specifically a vhd, from on storage account to another storage account. The app that I am writing has owner access to both storage accounts and can run other operation on these storage accounts. The vhd does not have a lease on it (not attached a VM). I have the following code but get a 403 forbidden response.

StorageCredentials scSource = new StorageCredentials(SourceStorageName, strSourceStorageKey);
StorageCredentials scTarget = new StorageCredentials(TargetStorageName, strTargetStorageKey);
CloudStorageAccount csaSource = new CloudStorageAccount(scSource, true);
CloudStorageAccount csaTarget = new CloudStorageAccount(scTarget, true);
CloudBlobClient cbcSource = csaSource.CreateCloudBlobClient();
CloudBlobClient cbcTarget = csaTarget.CreateCloudBlobClient();
CloudBlobContainer bcSource = cbcSource.GetContainerReference(SourceContainer);
CloudBlobContainer bcTarget = cbcTarget.GetContainerReference(TargetContainer);
CloudBlob cbSource = bcSource.GetBlobReference(strSourceDiskName);
CloudBlob cbTarget = bcTarget.GetBlobReference(strTargetDiskName);
Task<string> tskCopy = cbTarget.StartCopyAsync(cbSource.Uri);
while (tskCopy.Status != TaskStatus.RanToCompletion)
{
    if (tskCopy.Exception != null)
    throw tskCopy.Exception;
    Thread.Sleep(2500);
}

Not sure why this is happening because I am able to copy a blob from one storage account to another via other tools (cloud berry etc).

2
Can you please check the ACL of the source container? The blobs for copying in the source container should be publicly available.Gaurav Mantri
Premium storage account container data can only be set to private access for the account owner.Jeremy
In this case, you would need to create a SAS URL on the source blob with at least Read permission and use that as source URL instead of blob's URL.Gaurav Mantri

2 Answers

1
votes

Kudos to Gaurav Mantri for pointing me in the right direction. After looking up Shared Access Signature I came upon this article from Microsoft https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-2/

This code to be specific:

SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5);
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write;

// Generate the shared access signature on the blob, setting the constraints directly on the signature.
string sasBlobToken = blob.GetSharedAccessSignature(sasConstraints);

// Return the URI string for the container, including the SAS token.
return blob.Uri + sasBlobToken;
-1
votes

Could you check if the blob is still registered in Azure Portal as a virtual disk? If so, please remove the disk reference but retain the associated VHD, so that the lease of that blob will be released.

If you don't want to remove the virtual disk reference in Azure Portal, you can create a blob snapshot for the associated blob, and input the snapshot as the blob source when copying blob.