Search code examples
azureazure-storageazure-storage-files

ShareSasBuilder generating an invalid signature


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?


Solution

  • 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());