I’m migrating (sigh) Windows Azure from 1.7 to version 2, and I’m now facing some troubles with the old authentication way. When I try to execute the next code (working with the old implementations of the Azure SDK)…
[...]
var policy = new SharedAccessBlobPolicy();
policy.SharedAccessStartTime = new DateTimeOffset(DateTime.UtcNow.AddMinutes(-5));
policy.SharedAccessExpiryTime = policy.SharedAccessStartTime.Value.AddMinutes(5);
policy.Permissions = SharedAccessBlobPermissions.Read;
var sas = blobContainer.GetSharedAccessSignature(policy)
var request = WebRequest.Create(string.Format("{0}/{1}{2}", containerUri, blobName, sas));
request.Method = "GET";
var headers = new NameValueCollection();
headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add(headers);
request.ContentLength = 0;
var response = (HttpWebResponse)request.GetResponse();
[...]
… the GetResponse() method gets mad at me, and throws a WebException saying “Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.“
The ResponseUri is http://127.0.0.1:10000/devstoreaccount1/testcontainer/testBlob?sv=2012-02-12&st=2013-01-22T09.52.27Z&se=2013-01-22T09.57.29Z&sr=c&sp=r&sig=WxFfIg9NxKodH7zGjKRym7RuXd61F5jlG6ILtG1UYPg%3D, and it looks fine to me. I thought it was a problem of the AccountKey, but I have the same issue when trying it on a real storage, with the correct key provided by the Azure portal.
Is there any property or new initializations to be done for the new REST API?
UPDATE: I’ve tried the console application developed by @Gaurav Mantri in his reply, but it still didn’t work for me. So, I suspect the problem could depends on the italian localization on my machine, or some things related to Windows 8 (on the machine of another colleague the console application didn’t work aswell, with the same Error 403, forbidden! thrown by the GetResponse). I noticed the URI we get differs from every single example I found on the net, so I see the starting and expiry times as (for example) 2013-01-22T09.52.27Z instead of 2013-01-22T09%3A52%3A27Z
Ok, I’ve found which was the problem.
Adding the line
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;to my code (or test initiliazer) will resolve the problem.Looking at the WindowsAzure.Storage sources, when the service creates the signature, it uses the format string “yyyy-MM-ddTHH:mm:ssZ”, without passing
CultureInfo.InvariantCultureas parameter to theToStringmethod. But for italian regional settings, the separator between hours, minutes and seconds are dots, where for US are two-point. So my local machine and the remote machine created two different signatures, and they weren’t able to match.I’m going to report this as bug (or issue), cause not everyone has the same regional settings.