Azure Blob 存储 REST API 签名

Azure Blob Storage REST API signature

我一直致力于概念验证,并希望针对 Azure 存储 REST API 进行测试。但是,我无法进行身份验证。我整天都在尝试阅读、调整和重写,但它仍然不起作用。我已经一步一步地阅读了文档。

我希望找到能解决这个问题的人。许多硬编码位,只是为了让它工作。我不断收到此错误作为响应

The MAC signature found in the HTTP request '' is not the same as any computed signature

谁能看到我脸上可能正盯着什么看?这让我发疯。

    var requestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
    var StorageAccountName = "<account removed>";
    var StorageKey = "<key removed>";

    using (var client = new HttpClient())
    {
        var stringToSign = new List<string>(){
        "GET"                                                                                               /*HTTP Verb*/  
        ,""                                                                                                 /*Content-Encoding*/  
        ,""                                                                                                 /*Content-Language*/  
        ,""                                                                                            /*Content-Length (include value when zero)*/  
        ,""                                                                                                 /*Content-MD5*/  
        ,""                                                                                                 /*Content-Type*/  
        ,""                                                                                                 /*Date*/  
        ,""                                                                                                 /*If-Modified-Since */  
        ,""                                                                                                 /*If-Match*/  
        ,""                                                                                                 /*If-None-Match*/  
        ,""                                                                                                 /*If-Unmodified-Since*/  
        ,""                                                                                                 /*Range*/  
        ,$"x-ms-date:{requestDateString}\nx-ms-version:2015-02-21"                                          /*CanonicalizedHeaders*/
        ,$"/{StorageAccountName}/ " + _containerName + "\ncomp:metadata\nrestype:container\ntimeout:20"     /*CanonicalizedResource*/
        };


        string signature;
        using (var hmac = new HMACSHA256(Convert.FromBase64String(StorageKey)))
        {
            var compiledStringToSign = (string.Join("\n", stringToSign));
            byte[] dataToHmac = Encoding.UTF8.GetBytes(compiledStringToSign);
            signature = Convert.ToBase64String(hmac.ComputeHash(dataToHmac));
        }

        //Send Request
        client.DefaultRequestHeaders.Add("x-ms-date", requestDateString);
        client.DefaultRequestHeaders.Add("x-ms-version", " 2015-02-21");
        client.DefaultRequestHeaders.Add("Authorization", $"SharedKey {StorageAccountName}:" + signature);

        var response = client.SendAsync(request);

//编辑 请求 URL 是 https://account.blob.core.windows.net/testcontainer/blobtest/blob1234

该错误与身份验证失败有关,所以我认为错误一定在签名中,但我真的看不到。我用 fiddler 检查了所有输出以确保它们匹配

如果您想获取blob内容,请尝试使用以下演示代码,它在我这边运行正常。

var blobStorageAccount = "account name";
var storageKey = "account key";
var containerName = "container name";
var requestMethod = "GET";
var blobName = "blob name"; // in your case:blobtest/blob1234
var dt = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var msVersion = "2015-02-21";
var clientRequestId = Guid.NewGuid().ToString();
var canHeaders = $"x-ms-client-request-id:{clientRequestId}\nx-ms-date:{dt}\nx-ms-version:{msVersion}";
var canResource = $"/{blobStorageAccount}/{containerName}/{blobName}"; //not the CanonicalizedResource : /myaccount/mycontainer\ncomp:metadata\nrestype:container\ntimeout:20
var signStr = $"{requestMethod}\n\n\n\n\n\n\n\n\n\n\n\n{canHeaders}\n{canResource}";
var auth = CreateAuthString(blobStorageAccount, signStr, storageKey);
var urlPath = $"https://{blobStorageAccount}.blob.core.windows.net/{containerName}/{blobName}";
Uri uri = new Uri(urlPath);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("x-ms-date", dt);
client.DefaultRequestHeaders.Add("x-ms-version", msVersion);
client.DefaultRequestHeaders.Add("x-ms-client-request-id", clientRequestId);
client.DefaultRequestHeaders.Add("Authorization", auth);
HttpResponseMessage response = client.SendAsync(request).Result;
var status =  response.IsSuccessStatusCode;


private static string CreateAuthString(string blobStorageAccount,string signStr,string blobStorageAccessKey)
{
   var signature = string.Empty;
   byte[] unicodeKey = Convert.FromBase64String(blobStorageAccessKey);
   using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
   {
      byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(signStr);
      signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
   }

     var authorizationHeader = String.Format(
         CultureInfo.InvariantCulture,
         "{0} {1}:{2}",
         "SharedKey",
         blobStorageAccount,
         signature);

       return authorizationHeader;
  }