2017-09-28 255 views
0

我一直在研究概念证明,并正在尝试针对Azure存储REST API进行测试。但是,我无法验证。我一整天都在尝试阅读,调整和改写,但仍然无法正常工作。我一直在逐步完成文档。Azure Blob存储REST API签名

我希望找到管理这个的人。大量的硬编码位,它只是让它工作。我不断收到此错误回响应

在HTTP请求“中发现的MAC签名”是不一样的任何计算签名

任何人都可以看到什么是可能的盯着我的脸?这让我很生气。

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

的错误是非常具体的关于身份验证失败,所以我认为,误差必须在签名,我真的不能看到它虽然。我检查了所有的输出与小提琴手,以确保它们匹配

+0

我可以问你为什么不使用Azure存储SDK为C#? –

+0

当没有SDK时,我曾经在Python中实现过这个功能。 AFAIK C#SDK在GitHub上是开源的,您可以查看代码 - 两年前,我发现该实现非常易读 –

+0

您是否也可以共享请求URL? –

回答

1

如果你想要得到的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

+0

这个工程,是需要在canonicalizedResource改变什么。我可以问你从哪里得到信息,因为它不符合Azure文档 – James

+0

根据[Get blob API],这似乎是一个文档问题(https://docs.microsoft.com/en-us/ rest/api/storageservices/get-blob)https://myaccount.blob.core.windows.net/mycontainer/myblob,我假设canonicalizedResource应该是'$“/ {blobStorageAccount}/{containerName}/{blobName}” '。 –