我有一個相當簡單的方法,它使用NEW Storage API創建SAS並將blob從一個容器複製到另一個容器。使用Microsoft.WindowsAzure.Storage創建共享訪問令牌返回403
我想用這個來複制blob BETWEEN STORAGE ACCOUNTS。因此,我有兩個存儲帳戶,具有完全相同的容器,並且我試圖將存儲帳戶的容器中的一個塊複製到另一個存儲帳戶的容器。
我不知道SDK是否爲此而構建,但看起來這將是一種常見的情況。
一些額外的信息:
- 我創建目標容器的令牌。 是否需要在源和目標上創建該令牌?註冊令牌需要時間嗎?我是否需要爲每個請求創建它,或者每個標記「生命期」只需創建一次?
我應該提到一個403是一個未經授權的結果http錯誤代碼。
private static string CreateSharedAccessToken(CloudBlobClient blobClient, string containerName)
{
var container = blobClient.GetContainerReference(containerName);
var blobPermissions = new BlobContainerPermissions();
// The shared access policy provides read/write access to the container for 10 hours:
blobPermissions.SharedAccessPolicies.Add("SolutionPolicy", new SharedAccessBlobPolicy()
{
// To ensure SAS is valid immediately we don’t set start time
// so we can avoid failures caused by small clock differences:
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
Permissions = SharedAccessBlobPermissions.Write |
SharedAccessBlobPermissions.Read
});
blobPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
container.SetPermissions(blobPermissions);
return container.GetSharedAccessSignature(new SharedAccessBlobPolicy(), "SolutionPolicy");
}
下我使用此標記調用拷貝操作,它返回一個403行:
var uri = new Uri(srcBlob.Uri.AbsoluteUri + blobToken);
destBlob.StartCopyFromBlob(uri);
我Azure.Storage的版本是2.1.0.2。
這裏是萬一完全複製方法,可以幫助:
private static void CopyBlobs(
CloudBlobContainer srcContainer, string blobToken,
CloudBlobContainer destContainer)
{
var srcBlobList
= srcContainer.ListBlobs(string.Empty, true, BlobListingDetails.All); // set to none in prod (4perf)
//// get the SAS token to use for all blobs
//string token = srcContainer.GetSharedAccessSignature(
// new SharedAccessBlobPolicy(), "SolutionPolicy");
bool pendingCopy = true;
foreach (var src in srcBlobList)
{
var srcBlob = src as ICloudBlob;
// Determine BlobType:
ICloudBlob destBlob;
if (srcBlob.Properties.BlobType == BlobType.BlockBlob)
{
destBlob = destContainer.GetBlockBlobReference(srcBlob.Name);
}
else
{
destBlob = destContainer.GetPageBlobReference(srcBlob.Name);
}
// Determine Copy State:
if (destBlob.CopyState != null)
{
switch (destBlob.CopyState.Status)
{
case CopyStatus.Failed:
log.Info(destBlob.CopyState);
break;
case CopyStatus.Aborted:
log.Info(destBlob.CopyState);
pendingCopy = true;
destBlob.StartCopyFromBlob(destBlob.CopyState.Source);
return;
case CopyStatus.Pending:
log.Info(destBlob.CopyState);
pendingCopy = true;
break;
}
}
// copy using only Policy ID:
var uri = new Uri(srcBlob.Uri.AbsoluteUri + blobToken);
destBlob.StartCopyFromBlob(uri);
//// copy using src blob as SAS
//var source = new Uri(srcBlob.Uri.AbsoluteUri + token);
//destBlob.StartCopyFromBlob(source);
}
}
最後的帳戶和客戶端(審覈)代碼:
var credentials = new StorageCredentials("BAR", "FOO");
var account = new CloudStorageAccount(credentials, true);
var blobClient = account.CreateCloudBlobClient();
var sasToken = CreateSharedAccessToken(blobClient, "content");
當我使用REST客戶端,這似乎工作... 有任何想法嗎?
多少時間你對SAS的創建和複製使用的URL之間發生? – MikeWo
它瞬間發生;我稱之爲SAS方法,稍後再調用StartCopyFromBlob()api調用。它可能與編碼uri有關嗎?我看到過有關REST客戶端可以工作的報告,但Azure SDK失敗了,但沒有看到任何解決方案。 – nocarrier
我剛剛意識到問題在於它是在兩個不同的賬戶之間進行 - 我認爲這意味着我需要兩個賬戶(目的地和來源)的信用卡?我不確定SAS如何在Blob內容服務器上工作.. – nocarrier