VivekParamasivam
VivekParamasivam

Reputation: 1154

Windows azure REST API to List containers issue

I'm trying to list the containers in my windows azure storage account. but i'm struck with an exception
"The remote server returned an error: (403) Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.."

But i have included the signature as per the instructions given, do any one find any mistake in my code ?

private static String SignThis(string StringToSign,string  Key,string  Account)
        {

            String signature = string.Empty;
            byte[] unicodeKey = Convert.FromBase64String(Key);
            using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
            {
                Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
                signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
            }

            String authorizationHeader = String.Format(
                System.Globalization.CultureInfo.InvariantCulture,
                "{0} {1}:{2}",
                "SharedKey",
                Account,
                signature);
            return authorizationHeader;
        }
        static void ListContainers()
        {
            Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
            string Key = @"MyStorageAccountKey";
            string Account = @"MyStorageAccountName";

            DateTime dt = DateTime.UtcNow;

            string dataStr = dt.ToString ("R",System.Globalization.CultureInfo.InvariantCulture);
            string StringToSign = String.Format("GET\n"
                + "\n" // content encoding
                + "\n" // content language
                + "\n" // content length
                + "\n" // content md5
                + "\n" // content type
                + "\n" // date
                + "\n" // if modified since
                + "\n" // if match
                + "\n" // if none match
                + "\n" // if unmodified since
                + "\n" // range
                + "x-ms-date:" + dataStr + "\nx-ms-version:2014-02-14\n" // headers
                + "/{0}\ncomp:list", Account);

            string auth = SignThis(StringToSign, Key, Account);
            string method = "GET";
            string urlPath = string.Format ("https://{0}.blob.core.windows.net/?comp=list", Account);
            Uri uri = new Uri(urlPath);
            HttpWebRequest reque = (HttpWebRequest)WebRequest.Create(uri);
            reque.Method = method;
            reque.Headers.Add("Authorization", auth);
            reque.Headers.Add("x-ms-date",dataStr);
            reque.Headers.Add("x-ms-version", "2014-02-14");

            using (HttpWebResponse response = (HttpWebResponse) reque.GetResponse ()) {
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string text = reader.ReadToEnd();
                }
            }
        }

Edit : String i Used to generate Signature

GET

x-ms-date:Tue, 14 Jul 2015 18:38:16 GMT
x-ms-version:2014-02-14
/MyStorageAccountName/
comp:list

Edit : I received the exception response :

<?xml version="1.0" encoding="utf-8"?><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:2fc74ef8-0001-0083-2664-be8850000000
Time:2015-07-14T18:38:18.0831721Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request '5rqWNl2i8kuZF6haCRqFr1S0viOM9eLjz4L/zU6GCsg=' is not the same as any computed signature. Server used following string to sign: 'GET

x-ms-date:Tue, 14 Jul 2015 18:38:16 GMT
x-ms-version:2014-02-14
/MyStorageAccountName/
comp:list'.</AuthenticationErrorDetail></Error>

Final Edit: After making all the changes specified by gauvrav, i found that the storagekey i used was wrong, after replacing the right one, it is working fine.

There may be other changes for this error: please refer this link

Upvotes: 1

Views: 936

Answers (1)

Gaurav Mantri
Gaurav Mantri

Reputation: 136186

Please change your StringToSign to:

        string StringToSign = String.Format("GET\n"
            + "\n" // content encoding
            + "\n" // content language
            + "\n" // content length
            + "\n" // content md5
            + "\n" // content type
            + "\n" // date
            + "\n" // if modified since
            + "\n" // if match
            + "\n" // if none match
            + "\n" // if unmodified since
            + "\n" // range
            + "x-ms-date:" + dataStr + "\nx-ms-version:2014-02-14\n" // headers
            + "/{0}/\ncomp:list", Account);//Notice an extra "/" after "{0}"

It was missing a / after account name placeholder (last line in the code above). Once you do that, you should be able to see the list of containers returned in XML format.

Upvotes: 3

Related Questions