2014-09-26 85 views
0

我正在嘗試爲Windows Azure REST API查詢(特別是列表表格)創建正確的身份驗證標頭,但所有查詢都返回403錯誤。我已經閱讀了我可以找到的每個文檔,但是沒有任何一個複製粘貼的代碼似乎也可以工作。下面是我拼湊起來,使用存儲模擬器:Windows Azure REST API SharedKeyLite身份驗證(存儲模擬器)

static String CreateAuthorizationHeader(String canonicalizedString) 
    { 
     String signature = String.Empty; 
     string storageAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="; 

     using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey))) 
     { 
      Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString); 
      signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac)); 
     } 

     return String.Format("devstoreaccount1:" + signature); 
    } 

    static void ListTables() 
    { 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri("http://127.0.0.1:10002/devstoreaccount1/Tables")); 
     if(request.Headers.Date.HasValue) { 
      Console.WriteLine("Has Date"); 
      return; 
     } 
     string date = DateTime.UtcNow.ToString("R"); 
     request.Headers.Add("x-ms-date", date); 

     string stringToSign = 
      string.Format(
       "{0}\n{1}", 
       date, 
       "/devstoreaccount1/Tables"); 
     Console.Write("signing:\n{0}\n\n", stringToSign); 

     String authorizationHeader = CreateAuthorizationHeader(stringToSign); 
     request.Headers.Authorization = new AuthenticationHeaderValue("SharedKeyLite", authorizationHeader); 

     Console.Write("Request string:\n{0}\n\n", request.ToString()); 

     var httpClient = new HttpClient(); 
     HttpResponseMessage response = httpClient.SendAsync(request).Result; 
     if (!response.IsSuccessStatusCode) 
     { 
      Console.Write("Status was {0:d} ({0}): {1}", response.StatusCode, response.ReasonPhrase); 
      return; 
     } 

     Console.WriteLine(response.Content.ReadAsStringAsync().Result); 
    } 

這是輸出:

signing: 
Fri, 26 Sep 2014 19:13:57 GMT 
/devstoreaccount1/Tables 

Request string: 
Method: GET, RequestUri: 'http://127.0.0.1:10002/devstoreaccount1/Tables', Version: 1.1, Content: <null>, Headers: 
{ 
    x-ms-date: Fri, 26 Sep 2014 19:13:57 GMT 
    Authorization: SharedKeyLite devstoreaccount1:9nDo0c6fy/cUcImLCKMHvPYKba56xdh5l5pWDMhh3+0= 
} 

Status was 403 (Forbidden): Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. 

任何人可以發現在這一個缺陷?有人可以使用這些相同的約束和假設發佈一個示例ListTables請求字符串,包括結果簽名字符串?

謝謝!

回答

2

根據文檔here(章節:構造規範化資源字符串),您需要將存儲帳戶名稱放兩次。

如果您使用存儲模擬器進行身份驗證,則在CanonicalizedResource字符串中會出現兩次帳戶名稱 。這是預期的 。如果您使用Azure存儲服務進行身份驗證,則 帳戶名稱將在CanonicalizedResource字符串中僅出現一次。

在此基礎上,請通過以下嘗試:

string stringToSign = 
      string.Format(
       "{0}\n{1}", 
       date, 
       "/devstoreaccount1/devstoreaccount1/Tables"); 

這應該做的伎倆。

+0

*嘆*我清楚地記得閱讀該段..顯然我沒有處理它。非常感謝! – bfops 2014-09-26 19:24:28