2015-07-14 3 views
1

Я пытаюсь перечислить контейнеры в моей учетной записи хранения в окнах azure. но я поражен исключением
«Удаленный сервер ответил на ошибку: (403) Серверу не удалось аутентифицировать запрос. Убедитесь, что значение заголовка авторизации сформировано правильно, включая подпись ..»Windows azure REST API для отображения содержимого контейнеров

Но у меня есть включая подпись в соответствии с инструкциями, можно ли найти какую-либо ошибку в моем коде?

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 я Используется для генерации Подписи

GET 

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

Edit: я получил ответ исключения:

<?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: После внесения всех изменений, указанных gauvrav, я обнаружил, что используемая мной клавиша хранения была неправильной, после замены правой, она работает нормально.

Там могут быть и другие изменения этой ошибки: см это link

+1

Ответ на ошибку должен включать в себя строку для подписки на используемую службу хранения, поэтому вы можете использовать ее для проверки того, не хватает ли вы чего-то в строке ввода. –

+0

спасибо, можете ли вы объяснить, как получить значение «строка-to-sign» службы хранения? – VivekParamasivam

+1

Что означает @ SerdarOzler-Microsoft, если вы запустите свой код и запустили Fiddler (или проверили ошибку, проанализировав ответ WebException, который вы получите), вы увидите в сообщении об ошибке StringToSign, используемом сервером. Вы можете сравнить это с вашим StringToSign, чтобы увидеть, что не соответствует. Я использовал этот трюк, чтобы найти проблему в вашем коде. –

ответ

3

Пожалуйста, измените StringToSign на:

 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}" 

Он пропускал / после имени учетной записи заполнителем (последняя строка в коде выше). После этого вы сможете увидеть список контейнеров, возвращаемых в формате XML.

+0

Спасибо за указание gaurav. я изменил его, получив ту же ошибку. Думаю, какая-то другая ошибка? – VivekParamasivam

+1

Хм ... это странно. Я просто попробовал, и он отлично работает для меня. Вот моя копия кода: http://pastebin.com/KusuaqPS. Можете ли вы запустить свой код и проследить запрос/ответ в Fiddler и поделиться им здесь? Две другие возможные причины для 403 ошибок: 1) Неверный ключ учетной записи 2) Часы на вашем компьютере медленные (скажем, более 15-20 минут). Также проверьте их. –

+0

ваш ответ дает большую надежду. Я раньше не пробовал скрипач, попробую и ответим вам в ближайшее время. Спасибо за ответ. – VivekParamasivam