问题
I have a private azure storage container and am trying out azure storage SAS, so that I can upload and download files. I am able to generate the signature, but it always throws me the Authentication Fail error
AuthenticationFailed
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:a9dce486-0001-0021-23f7-d8f6dc000000 Time:2017-05-30T03:45:56.6617677Z Signature did not match. String to sign used was r 2017-05-30T03:40:48Z 2017-05-30T03:55:48Z /blob/{myaccount}/{mycontainer}/11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg2016-05-31
This is the code I have which generates a signature for me to use, and returns the full URI to access the file.
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;
This is the signature it generates
?sv=2016-05-31&sr=b&sig=9fUwDWfdtUifv9iZXJKgILEM7Yx1uP3Ku0vrspjWyz8%3D&st=2017-05-30T03%3A40%3A43Z&se=2017-05-30T03%3A55%3A43Z&sp=r
I used the Azure portal to generate the signature and it works fine. I append it and am able to download the file as usual. This is the signature it generates
?sv=2016-05-31&ss=b&srt=sco&sp=r&se=2017-05-30T03:57:25Z&st=2017-05-30T03:52:25Z&spr=https&sig=JOnhkge0QWNdv8sXJjb5GazTo9c34KH1IvZBvcNgjHo%3D
I highly suspect its an issue with the timestamp. Because I can see some differences in the timestamp between what I generate from the code, and what is generated from the portal.
Any ideas is much appreciated. Thanks.
EDIT I updated the code to add one day till expiry and removed the start time, this is the signature now
?sv=2016-05-31&sr=b&sig=73m3%2Bj%2BUsFk537vd8a7F%2BdpdON1Pg2RZ1IRynMH4zGA%3D&se=2017-05-31T06%3A12%3A07Z&sp=r
but it still doesnt allow me to download the file. Same error message.
Signature did not match. String to sign used was r 2017-05-31T06:12:07Z /blob/{MyAcc}/{My Container}/11e1575f-d3ad-40cc-b1ce-32e24dc20324.jpg 2016-05-31
回答1:
I also can't reproduced the issue using the code. Here is a method which could generate SAS without using the GetSharedAccessSignature method. Please try it and check whether it can work on your side.
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)));
}
}
来源:https://stackoverflow.com/questions/44253305/azure-storage-sas-authenticationfailed