I'm using the Azure.Storage.Blob
library to generate a SasToken, but I get instead a Sas Uri. I looked for examples online and in the docs.
I tried to generate a token myself but I didn't succeed in doing so. I even tried creating a SharedKeyLite but that didn't work aswell.
My code for SharedKeyLite:
var stringToSign = $"{DateTimeOffset.UtcNow.ToString("R", CultureInfo.InvariantCulture)}\n${canonicalizedResource}";
var hmac = new HMACSHA256(Convert.FromBase64String(storageAccountKey));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
return Convert.ToBase64String(hash);
My request:
URI: https://<myAccount>.blob.core.windows.net/<pathToFile>
# Headers
Authorization: SharedKeyLite <myAccount>:<keyFromAbove>
x-ms-date: date
x-ms-version: 2014-02-14
Error:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Why doesn't Azure.Storage.Blob
generate a SAS Token?
Use the Azure CLI to get the SAS token from the Storage Account.
az storage blob generate-sas \ --account-name {Storage Account name} \
--container-name {container name} \--name {blob name} \--permissions
{permissions to grant} \--expiry {datetime to expire the SAS token} \
--services {storage services the SAS allows} \--resource-types {resource types the SAS allows}
Example:
CONNECTION_STRING=<connection-string> az storage blob generate-sas \
--account-name MyStorageAccount \ --container-name MyContainer \
--name MyBlob \ --permissions racdw \ --expiry 2020-06-15
For more details refer this link
Another method to generate SAS Token
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)));
}
}
For more details refer this thread