2017-05-30 159 views
0

我有一個私人的Azure存儲容器,正在嘗試使用Azure存儲SAS,以便我可以上傳和下載文件。 我能夠生成簽名,但它總是拋出我的身份驗證失敗的錯誤Azure存儲SAS身份驗證失敗

AuthenticationFailed 服務器無法驗證請求。確保授權標頭的值正確形成,包括 簽名。 RequestId:a9dce486-0001-0021-23f7-d8f6dc000000 Time:2017-05-30T03:45:56.6617677Z 簽名不符。使用的字符串是r 2017-05-30T03:40:48Z 2017-05-30T03:55:48Z /blob/{myaccount}/{mycontainer}/11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg

2016年5月31日

這是我有產生對我來說,使用簽名的代碼,並返回完整的URI來訪問文件。

var accountAndKey = new StorageCredentials("******", "*********************"); 
var storageAccount = new CloudStorageAccount(accountAndKey, true); 

var sasConstraints = new SharedAccessBlobPolicy(); 
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5); 
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10); 
sasConstraints.Permissions = SharedAccessBlobPermissions.Read; 


CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); 
CloudBlobContainer container = blobClient.GetContainerReference("*****"); 
CloudBlockBlob blockBlob = container.GetBlockBlobReference("11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg"); 

var sasBlobToken = blockBlob.GetSharedAccessSignature(sasConstraints); 

var sas = blockBlob.Uri + sasBlobToken; 

return sas; 

這是它產生

?SV = 2016年5月31日& SR = B & SIG = 9fUwDWfdtUifv9iZXJKgILEM7Yx1uP3Ku0vrspjWyz8%3D & ST = 2017-05-30T03%3A40%3A43Z &簽名se = 2017-05-30T03%3A55%3A43Z & sp = r

我使用Azure門戶來生成簽名,它工作正常。我追加它,並能像往常一樣下載文件。 這是它產生

SV = 2016年5月31日& SS = B & SRT = SCO & SP = R & SE = 2017-05-30T03簽名:57:25Z & ST = 2017- 05-30T03:52:25Z & SPR = HTTPS & SIG = JOnhkge0QWNdv8sXJjb5GazTo9c34KH1IvZBvcNgjHo%3D

我高度懷疑其與時間戳的問題。因爲我可以看到從代碼生成的內容與從門戶生成的內容之間的時間戳差異。

任何想法非常感謝。謝謝。

編輯 我更新的代碼添加一天忙到到期並取消了開始時間,這是簽名現在

?SV = 2016年5月31日& SR = B & SIG = 73立方米%2BJ%2BUsFk537vd8a7F%2BdpdON1Pg2RZ1IRynMH4zGA%3D & SE = 2017-05-31T06%3A12%3A07Z & SP = R

,但它仍然犯規讓我下載的文件。相同的錯誤消息。

簽名不符。串籤使用爲r 2017-05-31T06:12:07Z/BLOB/{MyAcc}/{我的容器} /11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg 2016年5月31日

+0

你的代碼對我來說看起來很好。你能通過刪除開始時間並增加代碼中的到期時間(比如說一天)來嘗試嗎? –

+0

@GauravMantri我編輯了代碼來完成更改,但仍然沒有運氣 –

+0

您使用什麼版本的SDK生成SAS令牌? –

回答

0

我也不能使用代碼來重現問題。這是一種可以在不使用GetSharedAccessSignature方法的情況下生成SAS的方法。請嘗試一下,檢查它是否可以在你身邊工作。

private static string GetSharedAccessSignature(
     string accountName, 
     string accountkey, 
     string blobContainer, 
     string blobName, 
     DateTimeOffset sharedAccessStartTime, 
     DateTimeOffset sharedAccessExpiryTime) 
{ 
    var canonicalNameFormat = $"/blob/{accountName}/{blobContainer}/{blobName}"; 
    var st = sharedAccessStartTime.UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ"); 
    var se = sharedAccessExpiryTime.UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ"); 
    var sasVersion = "2016-05-31"; 

    string stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}\n{12}", new object[] 
    { 
     "r", 
     st, 
     se, 
     canonicalNameFormat, 
     string.Empty, 
     string.Empty, 
     string.Empty, 
     sasVersion, 
     string.Empty, 
     string.Empty, 
     string.Empty, 
     string.Empty, 
     string.Empty 
    }); 

    var sas = GetHash(stringToSign, accountkey); 

    var credentials = 
     $"?sv={sasVersion}&sr=b&sig={UrlEncoder.Default.Encode(sas)}&st={UrlEncoder.Default.Encode(st)}&se={UrlEncoder.Default.Encode(se)}&sp=r"; 

    string blobUri = $"https://{accountName}.blob.core.windows.net/{blobContainer}/{blobName}"; 
    return blobUri + credentials; 
} 

private static string GetHash(string stringToSign, string key) 
{ 
    byte[] keyValue = Convert.FromBase64String(key); 

    using (HMACSHA256 hmac = new HMACSHA256(keyValue)) 
    { 
     return Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign))); 
    } 
} 
+0

你好,我試過了代碼,如果在本地存儲模擬器上工作,使用生成的簽名時失敗 –

+0

請仔細檢查存儲帳戶名稱和用於生成SAS的帳戶密鑰對?帳號密鑰是否過期?您是否錯誤地使用帳戶連接字符串而不是帳戶密鑰?由於生成的SAS操作在本地運行。如果帳戶名稱和帳戶密鑰無效,它將不會驗證它。 – Amor

+0

我現在覺得很愚蠢,是的,你說的是錯誤的賬戶密鑰。我認爲它是好的,因爲我能夠成功地獲得blob客戶端,容器和blob引用。我不知道一切都是在當地完成的......非常感謝! –