2014-09-26 48 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