REST Api 使用访问密钥到 Azure Blob 存储

Posted

技术标签:

【中文标题】REST Api 使用访问密钥到 Azure Blob 存储【英文标题】:REST Api to Azure blob storage using Access key 【发布时间】:2019-11-08 12:05:00 【问题描述】:

我们正在尝试在不使用 Azure SDK 的情况下从 azure blob 存储访问 blob,

我们正在尝试通过 Azure REST API 通过共享密钥进行访问,为此我们需要生成授权标头,但是当我尝试从访问密钥创建签名时出现以下错误

“服务器未能验证请求。请确保 Authorization 标头的值格式正确,包括签名。”

“在 HTTP 请求 'key hash' 中找到的 MAC 签名与任何计算的签名都不相同”

需要帮助生成正确的授权标头,我们已按照文档进行操作

https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key

https://docs.microsoft.com/en-gb/rest/api/storageservices/authorization-for-the-azure-storage-services?redirectedfrom=MSDN

我们也在邮递员中尝试过,但我们得到了同样的错误。

     string signWithAccountKey(string stringToSign, string accountKey)
     
            var hmacsha = new System.Security.Cryptography.HMACSHA256();
            hmacsha.Key = Convert.FromBase64String(accountKey);
            var signature = hmacsha.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
            return Convert.ToBase64String(signature);
     

在 HTTP 请求“密钥哈希”中找到的 MAC 签名与任何计算的签名都不相同

【问题讨论】:

请编辑您的问题分享完整代码。还请告诉我们您尝试执行的 REST API 操作。您在计算 stringToSign 时很可能做错了什么。 你好 Naik,你能按照答案解决你的问题吗?如果已解决,请帮助将其标记为答案?谢谢。关注此guide 了解如何标记。 【参考方案1】:

我为List Blobs api 编写下面的代码。您可以关注/修改我的代码并尝试使用其他 blob api。

class Program


  static void Main(string[] args)
   
     ListBlobs();

      Console.WriteLine("done");
      Console.ReadLine();    
     


static void ListBlobs()

    string Account = "xxxx";
    string Key = "xxxx";
    string Container = "aa1";
    string apiversion = "2018-03-28";

    DateTime dt = DateTime.UtcNow;
    string StringToSign = String.Format("GET\n"
        + "\n" // content encoding
        + "\n" // content language
        + "\n" // content length
        + "\n" // content md5
        + "\n" // content type
        + "\n" // date
        + "\n" // if modified since
        + "\n" // if match
        + "\n" // if none match
        + "\n" // if unmodified since
        + "\n" // range
        + "x-ms-date:" + dt.ToString("R") + "\nx-ms-version:"+apiversion+"\n" // headers
        + "/0/1\ncomp:list\nrestype:container", Account, Container);

    string auth = SignThis(StringToSign, Key, Account);

    Console.WriteLine($"the date is: dt.ToString("R")");
    Console.WriteLine($"the auth token is: auth");
    Console.WriteLine("*********");
    string method = "GET";
    string urlPath = string.Format("https://0.blob.core.windows.net/1?restype=container&comp=list", Account, Container);
    Uri uri = new Uri(urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = method;
    request.Headers.Add("x-ms-date", dt.ToString("R"));
    request.Headers.Add("x-ms-version", apiversion);
    request.Headers.Add("Authorization", auth);

    Console.WriteLine("***list all the blobs in the specified container, in xml format***");
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    

        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        
            Console.WriteLine(reader.ReadToEnd());
        
    



private static String SignThis(String StringToSign, string Key, string Account)
        
            String signature = string.Empty;
            byte[] unicodeKey = Convert.FromBase64String(Key);
            using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
            
                Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
                signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
            

            String authorizationHeader = String.Format(
                  CultureInfo.InvariantCulture,
                  "0 1:2",
                  "SharedKey",
                  Account,
                  signature);

            return authorizationHeader;
        


   

在visual studio和postman中的测试结果:

【讨论】:

感谢您的示例...一切正常。

以上是关于REST Api 使用访问密钥到 Azure Blob 存储的主要内容,如果未能解决你的问题,请参考以下文章

Azure Key Vault Rest API 获取密钥 401

使用共享访问密钥上传到 Azure Blob 存储

密钥库身份验证 (REST API)

在 Winrt 中使用带有 Rest API 的 Azure,签名有问题

Azure 云存储凭据的保存位置

如何修复“访问令牌来自错误的受众或资源。”尝试使用 MSAL 令牌访问 Azure 的 REST api 时