c# - Windows Azure REST API SharedKeyLite 身份验证(存储模拟器)

标签 c# rest authentication azure

我正在尝试为 Windows Azure REST API 查询(特别是列出表)创建正确的身份验证 header ,但我的所有查询都返回 403 错误。我已经阅读了我能找到的所有文档,但复制粘贴的代码似乎都不起作用。以下是我使用存储模拟器拼凑而成的内容:

    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 请求字符串吗?

谢谢!

最佳答案

基于文档here (部分:构造规范化资源字符串),您需要将存储帐户名称输入两次。

If you are authenticating against the storage emulator, the account name will appear twice in the CanonicalizedResource string. This is expected. If you are authenticating against Azure storage services, the account name will appear only one time in the CanonicalizedResource string.

基于此,请尝试以下操作:

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

这应该可以解决问题。

关于c# - Windows Azure REST API SharedKeyLite 身份验证(存储模拟器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26066640/

相关文章:

java - 如何使用 SOAP UI 测试响应内容类型

php - laravel 5.5 资源 restful API

rest - 将域作为参数添加到 HTTP 基本身份验证

c# - faSTLine 图表中显示的空数据点不正确

c# - 在(字典)索引器上使用 C# 的 ref 特性

c# - 可用于帮助生成 HTML 的工具/SDK 有哪些?

apache - SVN session 问题

c# - 获取从 C# 代码到 javascript 的响应

rest - Docker : java.net.ConnectException:连接被拒绝 - 在端口 8083 上运行的应用程序无法访问端口 3000 上的其他应用程序

javascript - Parse.com Javascript API 登录