Azure表的POST请求中的授权标头

时间:2013-08-30 15:30:46

标签: azure header authorization azure-table-storage

我已经完成并尝试了所有内容以便将实体插入Azure表,但到目前为止,我仍然得到相同的错误“StatusCode:403,ReasonPhrase:'服务器无法验证请求。确保值授权标头的正确形成,包括签名。'“

现在,我尝试使用ShareKey和SharedKeyLite(Azure Storage Explorer使用SharedKeyLite)

public static async Task<string> InsertEntityAsync(string tableName, Position position)
    {
        string uri = @"https://" + Utilities.Account + ".table.core.windows.net/" + tableName;
        return await Utilities.UploadEntityAsync(tableName,uri,position);
    }
public static async Task<string> UploadEntityAsync(string urlPath, string uri, Position position)
    {
        string body = buildBodyForInsertOperation(position);

        HttpClient request = new HttpClient();
        string formatedTime = Authentication.FormatedTime();
        request.DefaultRequestHeaders.Add("x-ms-date", formatedTime);

        //Adding the Authorization header to the request
        string authorization = Authentication.GetSignedString("POST",formatedTime, urlPath, Utilities.Account, Utilities.Key);
        request.DefaultRequestHeaders.Add("Authorization", authorization);

        request.DefaultRequestHeaders.TryAddWithoutValidation("Content-Length", body.Length.ToString());


        HttpResponseMessage messageResult = await request.PostAsync(uri, new StringContent(body, UTF8Encoding.UTF8, "application/atom+xml"));
        return messageResult.ToString();
    }

 public static string GetSignedString(string httpMethod, string time, string urlPath, string account, string key)
    {
           String contentMD5 = String.Empty;
String contentType = "application/atom+xml";
String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
String stringToSign = String.Format(
      "{0}\n{1}\n{2}\n{3}\n{4}",
      httpMethod,
      contentMD5,
      contentType,
      time,
      canonicalizedResource);

        string signedKey = SignThis(stringToSign, key, account);
        return signedKey;
    }
    private static String SignThis(String canonicalizedString,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(canonicalizedString);
            signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
        }

        String authorizationHeader = String.Format(
              CultureInfo.InvariantCulture,
              "{0} {1}:{2}",
              "SharedKeyLite",
              Account,
              signature);

        return authorizationHeader;
    }

time参数根据Azure的要求进行格式化,除此之外我不知道还有什么或尝试。我试图在没有httpMethod的情况下发出请求,没有contentMD5,没有内容类型和所有类型的组合,但仍然。

我很确定SignThis(...)方法有效,因为我正在使用它来签署GET请求来查询实体,所以任何帮助或单词都会对我有所帮助。感谢

/ 被修改 / 我正在附加UploadEntityAsync方法,在我的情况下,我有一个名为Position in Azure的表,所以我正在构建XML,无论如何,这不是什么错,因为我已经将我的buided XML与使用Azure存储资源管理器的XML进行了比较提琴手,还有他们。唯一的问题是签名

1 个答案:

答案 0 :(得分:1)

所以我发现代码存在一些问题:

  • 您已选择使用 SharedKeyLite ,但您在代码中用于创建stringToSign的格式适用于 {{1} } 即可。如果您想使用SharedKey,请尝试使用以下内容创建SharedKeyLite

    stringToSign

有关详细信息,请参阅此处:http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx

  • 我发现您创建 stringToSign = String.Format("{0}\n{1}", time, canonicalizedResource); 的方式存在问题。出于某种原因,如果我使用您的代码,我总是会收到403错误。试试这个:

    StringContent

请尝试使用此代码。它使用SharedKey:

    var stringContent = new StringContent(body);
    stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/atom+xml");
    HttpResponseMessage messageResult = await request.PostAsync(uri, stringContent);