2017-09-28 5 views
0

J'ai travaillé sur une validation de principe et je souhaite effectuer des tests sur l'API Azure Storage REST. Cependant, je ne peux pas m'authentifier. J'ai essayé toute la journée avec la lecture et l'ajustement et la réécriture et cela ne fonctionne toujours pas. J'ai parcouru la documentation étape par étape. Je souhaite trouver quelqu'un qui a réussi cela. Beaucoup de bits codés en dur, c'est juste pour le faire fonctionner. Je continue à obtenir cette erreur de retour en réponseAzure Blob Storage Signature de l'API REST

La signature MAC trouvée dans la requête HTTP « » est pas la même que toute signature calculée

Quelqu'un peut-il voir ce qui est peut-être me regarder en face? Cela me rend fou.

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); 

// modifier L'URL de la requête est https://account.blob.core.windows.net/testcontainer/blobtest/blob1234

L'erreur est tout à fait spécifique sur l'authentification à défaut, donc je pense que l'erreur doit être dans la signature, je ne vois vraiment pas cependant. J'ai vérifié toutes les sorties avec fiddler pour m'assurer qu'elles correspondent

+0

Puis-je demander pourquoi ne pas utiliser Azure SDK stockage pour C#? –

+0

Je l'ai déjà implémenté en Python lorsqu'il n'y avait pas de SDK. AFAIK le C# SDK est open source chez GitHub et vous pouvez consulter le code - il y a deux ans j'ai trouvé l'implémentation très lisible –

+0

Pouvez-vous partager l'URL de la requête aussi? –

Répondre

1

Si vous voulez obtenir le contenu blob, essayez d'utiliser le code de démonstration suivant, il fonctionne correctement de mon côté.

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

Cela fonctionne, le changement canonicalizedResource est ce qui était nécessaire. Puis-je demander d'où provient l'information car elle ne correspond pas à la documentation Azure? – James

+0

Il semble que ce soit un problème de document, selon [Get blob API] (https://docs.microsoft.com/fr-fr/ repos/api/storageservices/get-blob) https://myaccount.blob.core.windows.net/mycontainer/myblob, je suppose que canonicalizedResource doit être '$"/{blobStorageAccount}/{containerName}/{blobName} " '. –