1
votes

I am using below code sample to create shared access signatures for private files stored inside Azure Blob storage. The generated Url is sometimes valid but most of the time is invalid due to authentication error.

public async Task<string> GetFileUrl(string containerName, string fileName)
{    
     ICloudBlob blob = await GetBlob(containerName, fileName);

     string signature = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
     {
           SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),
           SharedAccessExpiryTime = DateTime.UtcNow.AddDays(7),
           Permissions = SharedAccessBlobPermissions.Read
     });

     return blob.Uri.AbsoluteUri + signature;
}

I receive following response when the formed SAS is not valid,

<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:</Message>
    <AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>

Following are the parameters for a URL that is failing to authenticate

sv=2016-05-31
sig=SbVzxo+dv28FvJP+Z9b1w6uvWUT72Pw1BSe3MIRooM0=
st=2017-03-30T11:52:35Z
se=2017-04-06T11:57:35Z
sr=b
sp=r
1
Can you try by removing the start time? Also, please tell us what version of Storage client library you're using.Gaurav Mantri
Actually, I tried adding it to fix to issue. It was not there before and it did not work.emre nevayeshirazi
Are you correctly escaping the value in the URI? The + characters might be causing issues.Martin Costello
I've done this very recently. The only significant difference is that I used a UriBuilder to build the Uri. So new UriBuilder(blob.Uri.AbsoluteUri){Query=signature}.Uri.AbsoluteUrispender
@It'satrap yes it was a silly mistake as always :) See my answer please. Thanks all for suggestions.emre nevayeshirazi

1 Answers

3
votes

I found the problem. I did not mention in question but the code for generation SAS is called via HTTTP client and the URL for accessing the Blob with SAS is located in Location header of the response.

I was trying to retrieve the URL with

response.Headers.Location.ToString();

but, I should have used

response.Headers.Location.OriginalString.ToString();

According to Microsoft the Location.ToString() returns the canonically unescaped form of the URI. That is why my signature was invalid and there were characters like + inside it.