Azure Blob 存储 REST API 签名

标签 azure azure-storage restful-authentication

我一直在进行概念验证,并希望针对 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;
  }

enter image description here

关于Azure Blob 存储 REST API 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46475634/

相关文章:

powershell - 使用快照复制 Azure Blob

java - RESTFUL API 中的几个登录

rest - JSON Web 签名 (JWS) 和 JSON Web token (JWT) 有什么区别?

azure - 使用 CloudTable 绑定(bind)到 v2 Azure Functions 中的表存储

azure - 如何将数组转换为ARM模板中一个对象的属性?

针对已删除的 Azure 容器的 Azure 警报

ruby-on-rails - Rails 错误:未初始化常量 ApplicationController::Authentication

authentication - 使用从另一个 IdP 返回的 SAML 2.0 工件在 MS Azure AD 中进行身份验证

azure - 尝试使用 Invoke-AzResourceAction 启动 Azure 容器实例时出错 : No HTTP resource was found that matches the request URI

javascript - 创建 BlobServiceWithSas 时不存在 'Access-Control-Allow-Origin' header