【问题标题】:PUT blob with Blob Service API in Postman - Authorization header在 Postman 中使用 Blob 服务 API 放置 blob - 授权标头
【发布时间】:2017-07-16 17:00:12
【问题描述】:

我需要帮助构建 Authorization 标头以 PUT 块 blob。

PUT\n\n\n11\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Sat, 25 Feb 2017 22:20:13 GMT\nx-ms-version:2015-02-21\n/myaccountname/mycontainername/blob.txt\n

我接受这个,UTF 8 编码它。然后我在我的 Azure 帐户中使用我的访问密钥,并用密钥对这个 UTF 8 编码字符串进行 HMAC sha256。然后我在base64中输出。我们称之为输出字符串。

我的授权标头如下所示:SharedKey myaccountname:output string

它不工作。

Postman 中的标头也有 x-ms-blob-type、x-ms-date、x-ms-version、Content-Length 和 Authorization。身体现在说你好世界。

谁能帮我在 Postman 中成功提出这个请求?

<?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:cdeb9a5e-0001-0029-5fb5-8f7995000000
Time:2017-02-25T22:22:32.0300016Z</Message>
    <AuthenticationErrorDetail>The MAC signature found in the HTTP request 'jiJtirohvi1syXulqkPKESnmQEJI4GpDU5JBn7BM/xY=' is not the same as any computed signature. Server used following string to sign: 'PUT


11

text/plain;charset=UTF-8






x-ms-date:Sat, 25 Feb 2017 22:20:13 GMT
x-ms-version:2015-02-21
/myaccountname/mycontainername/blob.txt'.</AuthenticationErrorDetail>
</Error>

编辑:

首先,我要感谢您和所有回复的人。我真的很感激。我有最后一个问题,然后我想我会准备好的!!我没有使用那个代码——我都是手工完成的。如果我有我的密钥:X2iiy6v47j1jZZH5555555555zzQRrIAdxxVs55555555555av8uBUNGcBMotmS7tDqas14gU5O/w== 因匿名而略有更改 - 我是否对其进行解码:使用在线 base64decoder。然后,当我的字符串现在看起来像这样时:PUT\n\n\n11\n\ntext/plain;charset=UTF-8\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Mon, 27 Feb 2017 21:53:13 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer/blob.txt\n 所以我在https://mothereff.in/utf-8 中运行它,然后在 HMAC 中使用我的解码密钥:https://www.liavaag.org/English/SHA-Generator/HMAC/ - 最后使用 sha256 和 base64。

这就是我将正确的字符串放在这里的方式吗?:SharedKey myaccount:&lt;string here&gt;

【问题讨论】:

  • 使用您提到的生成代码的工具由于“\n”字符而与签名不匹配。我写了一个online tool 来生成签名。我也更新了答案。

标签: api azure azure-blob-storage


【解决方案1】:

我认为您在此处指定 StringToSign 的方式存在问题:

PUT\n\n\n11\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Sat, 2017 年 2 月 25 日 22:20:13 GMT\nx-ms-version:2015-02-21\n/myaccountname/mycontainername/blob.txt\n

如果您注意到服务器返回的错误消息,则服务器签名的字符串与您的不同,不同之处在于服务器使用Content-Type (text/plain;charset=UTF-8) 进行签名计算,而您没有。请在您的代码中包含此内容类型,一切正常。

这是我使用的示例代码(仅部分):

        var requestMethod = "PUT";
        var urlPath = "test" + "/" + "myblob.txt";
        var storageServiceVersion = "2015-12-11";
        var date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
        var blobType = "BlockBlob";
        var contentBytes = Encoding.UTF8.GetBytes("Hello World");
        var canonicalizedResource = "/" + accountName + "/" + urlPath;
        var canonicalizedHeaders = "x-ms-blob-type:" + blobType + "\nx-ms-date:" + date + "\nx-ms-version:" + storageServiceVersion + "\n";
        var stringToSign = requestMethod + "\n" +
            "\n" + //Content Encoding
            "\n" + //Content Language
            "11\n" + //Content Length
            "\n" + //Content MD5
            "text/plain;charset=UTF-8" + "\n" + //Content Type
            "\n" + //Date
            "\n" + //If - Modified - Since
            "\n" + //If - Match
            "\n" + //If - None - Match
            "\n" + //If - Unmodified - Since
            "\n" + //Range +
           canonicalizedHeaders +
           canonicalizedResource;
        string authorizationHeader = GenerateSharedKey(stringToSign, accountKey, accountName);


    private static string GenerateSharedKey(string stringToSign, string key, string account)
    {
        string signature;
        var unicodeKey = Convert.FromBase64String(key);
        using (var hmacSha256 = new HMACSHA256(unicodeKey))
        {
            var dataToHmac = Encoding.UTF8.GetBytes(stringToSign);
            signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
        }
        return string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKey", account, signature);
    }

【讨论】:

    【解决方案2】:

    根据你的报错信息,说明授权签名不正确。

    如果Content-Type "text/plain; charset=UTF-8"不包含在header中,请在stringTosign和postman中添加。

    当我们尝试获取签名时,我们需要确保 length of the blob.txt 与 stringTosign 中的 Content length 匹配。这意味着请求正文长度应与 stringTosign 中的内容长度匹配。

    我用 Postman 对其进行了测试,它可以正常工作。我们可以用另一个SO Thread中的代码获取签名。以下是我的详细步骤

    1. 添加以下标题

    1. 添加请求正文(例如:Hello World)

    1. 发送 put blob 请求。

    更新:

    请尝试使用online tool生成签名进行测试。

    【讨论】:

      猜你喜欢
      • 2016-02-24
      • 2021-10-30
      • 2018-03-24
      • 2019-01-18
      • 2021-12-08
      • 2018-01-14
      • 2017-06-09
      • 2021-08-27
      • 1970-01-01
      相关资源
      最近更新 更多