C#Azure REST API:MAC签名[...]与任何计算签名不同

时间:2017-08-08 13:56:32

标签: c# rest azure

我正在开发一个使用Azure blob存储的项目。

我的代码发送以下内容,以便将jpeg图像上传到Azure存储blob:

PUT https://<storageAccount>.blob.core.windows.net/<container>/ca13bd3a-d805-46ce-994e-e70560a54cda.jpg HTTP/1.1
x-ms-date: Tue, 08 Aug 2017 10:05:24 GMT
Date: Tue, 08 Aug 2017 10:05:24 GMT
x-ms-version: 2009-09-19
Content-Type: image/jpeg
x-ms-blob-type: BlockBlob
Accept-Charset: UTF-8
Authorization: SharedKey <storageAccount>:<computed hash>
Host: <storageAccount>.blob.core.windows.net
Content-Length: 498732
Expect: 100-continue
Connection: Keep-Alive

<jpeg image>

使用以下代码创建Autorization标头:

    byte[] SignatureBytes = System.Text.Encoding.UTF8.GetBytes(MessageSignature);
    System.Security.Cryptography.HMACSHA256 SHA256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(StorageKey));
    String AuthorizationHeaderRes = "SharedKey " + StorageAccount + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));

但结果是,我收到403错误,并显示以下消息:

The MAC signature found in the HTTP request '<request id>' is not the same as any computed signature. Server used following string to sign: 'PUT


498732

image/jpeg






x-ms-blob-type:BlockBlob
x-ms-date:Tue, 08 Aug 2017 10:05:24 GMT
x-ms-version:2009-09-19
/<storageAccount>/<storageAccount>/ca13bd3a-d805-46ce-994e-e70560a54cda.jpg

我在网上尝试了很多解决方案,因此我知道以下内容:

  • DateTime没问题
  • 我可以获取容器中的blob列表

编辑1:

MessageSignature:

  string MessageSignature;

        if (IsTableStorage)
        {
            MessageSignature = String.Format("{0}\n\n{1}\n{2}\n{3}",
                method,
                "application/atom+xml",
                now.ToString("R", System.Globalization.CultureInfo.InvariantCulture),
                GetCanonicalizedResource(request.RequestUri, StorageAccount)
                );
        }
        else
        {
            MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
                method,
                (method == "GET" || method == "HEAD") ? String.Empty : request.ContentLength.ToString(),
                ifMatch,
                GetCanonicalizedHeaders(request),
                GetCanonicalizedResource(request.RequestUri, StorageAccount),
                md5
                );
        }

编辑2:

GetCanonicalizedHeaders:

        public string GetCanonicalizedHeaders(HttpWebRequest request)
    {
        ArrayList headerNameList = new ArrayList();
        StringBuilder sb = new StringBuilder();
        foreach (string headerName in request.Headers.Keys)
        {
            if (headerName.ToLowerInvariant().StartsWith("x-ms-", StringComparison.Ordinal))
            {
                headerNameList.Add(headerName.ToLowerInvariant());
            }
        }
        headerNameList.Sort();
        foreach (string headerName in headerNameList)
        {
            StringBuilder builder = new StringBuilder(headerName);
            string separator = ":";
            foreach (string headerValue in GetHeaderValues(request.Headers, headerName))
            {
                string trimmedValue = headerValue.Replace("\r\n", String.Empty);
                builder.Append(separator);
                builder.Append(trimmedValue);
                separator = ",";
            }
            sb.Append(builder.ToString());
            sb.Append("\n");
        }
        return sb.ToString();
    }

GetCanonicalizedResource:

public string GetCanonicalizedResource(Uri address, string accountName)
    {
        StringBuilder str = new StringBuilder();
        StringBuilder builder = new StringBuilder("/");
        builder.Append(accountName);
        builder.Append(address.AbsolutePath);
        str.Append(builder.ToString());
        NameValueCollection values2 = new NameValueCollection();
        if (!IsTableStorage)
        {
            //NameValueCollection values = System.Web.HttpUtility.ParseQueryString(address.Query);
            NameValueCollection values = this.ParseQueryString(address.Query);
            foreach (string str2 in values.Keys)
            {
                ArrayList list = new ArrayList(values.GetValues(str2));
                list.Sort();
                StringBuilder builder2 = new StringBuilder();
                foreach (object obj2 in list)
                {
                    if (builder2.Length > 0)
                    {
                        builder2.Append(",");
                    }
                    builder2.Append(obj2.ToString());
                }
                values2.Add((str2 == null) ? str2 : str2.ToLowerInvariant(), builder2.ToString());
            }
        }
        ArrayList list2 = new ArrayList(values2.AllKeys);
        list2.Sort();
        foreach (string str3 in list2)
        {
            StringBuilder builder3 = new StringBuilder(string.Empty);
            builder3.Append(str3);
            builder3.Append(":");
            builder3.Append(values2[str3]);
            str.Append("\n");
            str.Append(builder3.ToString());
        }
        return str.ToString();
    }

编辑3:

MessageSignature内容(注意:日期已更改,但无关紧要):

PUT


498732








x-ms-blob-type:BlockBlob
x-ms-date:Tue, 08 Aug 2017 15:09:52 GMT
x-ms-version:2009-09-19
/<storageAccount>/<container>/ca13bd3a-d805-46ce-994e-e70560a54cda.jpg

0 个答案:

没有答案