I'm trying to generate a SAS signed URL to download a file from an Azure file storage (using this as an example):
using Azure.Storage;
using Azure.Storage.Files.Shares;
using Azure.Storage.Files.Shares.Models;
using Azure.Storage.Sas;
(...)
public Uri getFileUri(string fileName)
{
string AccountName = WebConfigurationManager.AppSettings["AzureStorageDepotAccountName"];
string AccountKey = WebConfigurationManager.AppSettings["AzureStorageDepotAccountKey"];
sharedKeyCredential = new StorageSharedKeyCredential(AccountName, AccountKey);
shareClient = new ShareClient(new Uri("https://sanitizedShare.file.core.windows.net/"), sharedKeyCredential);
ShareDirectoryClient directory = shareClient.GetDirectoryClient("sanitizedDir");
ShareFileClient file = directory.GetFileClient(fileName);
var shareSasBuilder = new ShareSasBuilder
{
ShareName = "sanitizedShare",
FilePath = file.Uri.LocalPath,
Protocol = SasProtocol.None,
StartsOn = DateTime.UtcNow.AddHours(-1),
ExpiresOn = DateTime.UtcNow.AddHours(+2),
IPRange = new SasIPRange(IPAddress.None, IPAddress.None)
};
shareSasBuilder.SetPermissions(ShareFileSasPermissions.Read);
return new Uri(file.Uri + "?" + shareSasBuilder.ToSasQueryParameters(sharedKeyCredential).ToString());
}
It returns a correct looking URL (https://sanitizedShare.file.core.windows.net/sanitizedDir/sanitizedFile?sv=2019-07-07&st=2020-05-27T19:36:55Z&se=2020-05-27T22:36:55Z&sr=f&sp=r&sig=l3bLiYlA9Y+Se1jC1g/F5A0T4yOT0nUJHUxyLhNksw8=
) but when I try it I get this error:
<Error>
<Code>AuthenticationFailed</Code>
<Message>
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:8c400781-e01a-0040-4266-347d43000000 Time:2020-05-27T20:36:56.2303652Z
</Message>
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>
At first I thought that I had the wrong credentials, but I'm using the same credentials elsewhere in my code and it can access the share. Do you know what the problem could be?
Make the following changes to your code:
1.add the file share name
at the end of the url when create the ShareClient
(Note:for the url, I see you're using fileshareName.file.core.windows.net
, it should be your_storage_account_name.file.core.windows.net
), like below:
var shareClient = new ShareClient(new Uri("https://your_storage_account_name.file.core.windows.net/the_share_name"), sharedKeyCredential);
2.in the code block of new ShareSasBuilder{}
, remove FilePath = file.Uri.LocalPath,
Then I tested the code(with the latest version of Azure.Storage.Files.Shares 12.2.1
), it generates a valid and working url with sastoken. My code as below:
string storageAccount= "yy1";
string password = "xxxx";
var sharedKeyCredential = new StorageSharedKeyCredential(storageAccount, password);
//the file share name is aaa
var shareClient = new ShareClient(new Uri("https://yy1.file.core.windows.net/aaa"), sharedKeyCredential);
ShareDirectoryClient directory = shareClient.GetDirectoryClient("a11");
ShareFileClient file = directory.GetFileClient("1.txt");
var shareSasBuilder = new ShareSasBuilder
{
ShareName = "aaa",
//FilePath = file.Uri.LocalPath,
Protocol = SasProtocol.None,
StartsOn = DateTime.UtcNow.AddHours(-1),
ExpiresOn = DateTime.UtcNow.AddHours(+2),
IPRange = new SasIPRange(IPAddress.None, IPAddress.None)
};
shareSasBuilder.SetPermissions(ShareFileSasPermissions.Read);
var url = new Uri(file.Uri + "?" + shareSasBuilder.ToSasQueryParameters(sharedKeyCredential).ToString());