2016-04-21 14 views
1

I-Code verwenden aus diesem MSDN-Artikel kopiert und geändert:Azure Blob 403 Forbidden SAS mit erstellen und verwenden BlobContainer

MSDN article about Azure SAS usage

ich die Azure Storage Emulator bin mit und kann die SAS erzeugen. Hier ein Beispiel:

http://127.0.0.1:10000/devstoreaccount1/7373df60-ad5f-462e-a55d-15c21c2de0e1?sv=2015-04-05&sr=c&si=ac&sig=bQAsuNUsj6MycN0aTyurVugHBMOlokwsXJA9xv7VeiU%3D 

kann ich den Edge-Browser verwenden, um die Blob-Container zur Liste von Anhängen:

&comp=list&restype=container 

so dass meine Verbindung sieht nun wie folgt aus:

http://127.0.0.1:10000/devstoreaccount1/7373df60-ad5f-462e-a55d-15c21c2de0e1?sv=2015-04-05&sr=c&si=ac&sig=bQAsuNUsj6MycN0aTyurVugHBMOlokwsXJA9xv7VeiU%3D&comp=list&restype=container 

Diese lässt mich denken, dass der SAS korrekt ist und der Speicheremulator funktioniert. Der Browser zeigt die Informationen für den Container und alle darin enthaltenen Blobs an.

Ich kann den Speicher Emulator Protokoll überprüfen und diese Meldung sehen:

4/21/2016 3:56:10 PM [AuthorizationFailure] [ActivityId=a79d230e-6596-4e43-8ef9-58943ee91b58] Unauthorized: Signed access not supported for this request with FailureReason InvalidOperationSAS 

Hier ist der Code, dass ich die SAS erstellen verwenden:

String policyName = "ac"; 

var storedPolicy = new SharedAccessBlobPolicy() 
{ 
    SharedAccessExpiryTime = DateTime.UtcNow.AddHours(expireHours), 
    Permissions = SharedAccessBlobPermissions.Read | 
    SharedAccessBlobPermissions.List | 
    SharedAccessBlobPermissions.Delete 
}; 

var permissions = container.GetPermissions(); 

permissions.SharedAccessPolicies.Clear(); 

permissions.SharedAccessPolicies.Add(policyName, storedPolicy); 

container.SetPermissions(permissions); 

string sasContainerToken = container.GetSharedAccessSignature(null, policyName); 

// Return the URI string for the container, including the SAS token. 

return container.Uri + sasContainerToken; 

Und hier ist der Code, den ich benutze

CloudBlobContainer container = new CloudBlobContainer(new Uri(sas)); // AzureBlob.GetBlobContainer(sas); // gets a new container 

if (! container.Exists()) // throws exception 
{ 
    throw new Exception("Container no longer exists for sas " + sas); 
} 

container.FetchAttributes(); 

Hier ist die Ausnahme: die CloudBlobContainer mit der SAS erstellen

Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (403) Forbidden. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden. 
    at System.Net.HttpWebRequest.GetResponse() 
    at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Core\\Executor\\Executor.cs:line 677 
    --- End of inner exception stack trace --- 
    at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Core\\Executor\\Executor.cs:line 604 
    at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(Boolean primaryOnly, BlobRequestOptions requestOptions, OperationContext operationContext) in c: 
    \\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Blob\\CloudBlobContainer.cs:line 1406 
    at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(BlobRequestOptions requestOptions, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Blob\\CloudBlobContainer.cs:line 1393 

Hier ist ein Link zu einem Artikel, der ein entfernter Verwandter zu sein scheint.

SO question about SAS

Antwort

3

der Grund Code versagt ist, weil, was Sie geschaffen haben eine Service Shared Access Signature (Service SAS) statt Account Shared Access Signature (Account SAS) ist. Um einen Blob-Container zu erstellen, müssten Sie einen Account SAS anstelle von Service SAS verwenden.

Von dieser Seite: https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx

Ein Kontoebene SAS, mit der Version 2015.04.05 eingeführt. Das Konto SAS delegiert Zugriff auf Ressourcen in einem oder mehreren der Speicher Dienste. Alle Operationen, die über einen Service-SAS verfügbar sind, sind ebenfalls über ein Konto SAS verfügbar. Darüber hinaus können Sie mit dem Konto SAS Zugriff auf Vorgänge delegieren, die für einen bestimmten Dienst gelten, z. B. als Get/Set-Diensteigenschaften und Get Service Stats.Sie können auch delegieren Zugriff auf Lesen, Schreiben und Löschen von Operationen auf Blob Container, Tabellen, Warteschlangen und Dateifreigaben, die nicht zulässig sind mit einem Service SAS. Weitere Informationen zum Konto SAS finden Sie unter Erstellen einer Konto-SAS für weitere Informationen.

Hier ist ein Beispielcode Konto SAS und es verwenden, erstellen einen Klecks Container zu erstellen:

 var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); 
     var blobClient = storageAccount.CreateCloudBlobClient(); 
     var blobSharedAccessPolicy = new SharedAccessAccountPolicy() 
     { 
      Services = SharedAccessAccountServices.Blob, 
      SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1), 
      Permissions = SharedAccessAccountPermissions.Write, 
      ResourceTypes = SharedAccessAccountResourceTypes.Container 
     }; 
     var sas = storageAccount.GetSharedAccessSignature(blobSharedAccessPolicy); 
     var containerName = "created-using-account-sas"; 
     var containerUri = string.Format("{0}{1}", storageAccount.BlobEndpoint, containerName); 
     var blobContainer = new CloudBlobContainer(new Uri(containerUri), new StorageCredentials(sas)); 
     blobContainer.Create(); 
     Console.WriteLine("Container created...."); 
+0

Hallo, Gaurav! Vielen Dank für Ihre Hilfe. Ich habe eine Fehlermeldung erhalten, bis ich diese Zeile geändert habe 'var containerUri = string.Format ("{0}/{1}", storageAccount.BlobEndpoint, containername); 'Ich habe geändert, um Berechtigungen zum Lesen, Schreiben, Erstellen, Auflisten hinzuzufügen. und Löschen Aber wenn ich versuche, einen Blob in den Container hochzuladen, bekomme ich 403 Verboten. Mein bestehender Code funktionierte gut zum Erstellen des Containers und zum Hochladen der Blobs. Meine Frage ist, kann ich die Berechtigungen anwenden und die SAS, nachdem ich den Container erstellen und die Blobs hochladen? Wenn nicht, wie vermeide ich den Fehler 403 beim Versuch, die Blobs hochzuladen? – Pete

+0

Ok, ich habe es einen Schritt weiter gemacht. Ich habe 'SharedAccessResourceTypes.Blob' hinzugefügt und konnte Blobs in den neuen Container hochladen. Das sas sieht so aus: http://127.0.0.1:10000/devstoreaccount1/45a56968-459a-4a65-995d-06e233e1d015?sv=2015-04-05&sig=zXJC6hIjD77c3b1oKZWlW9YtuHMF78zR7NxVc%2FcYMQs%3D&se=2016-04-22T17%3A20% 3A40Z & srt = co & ss = b & sp = rcwdl' Wenn ich versuche, diese sas in einem anderen Programm zu verwenden, bekomme ich ** System.ArgumentException: Fehlende obligatorische Parameter für gültige Shared Access-Signatur ** Irgendwelche Ideen dazu? – Pete

+0

'Wenn ich versuche, diese sas in einem anderen Programm zu verwenden '-> Können Sie das genauer beschreiben? Es ist vielleicht keine schlechte Idee, das als neue Frage zu veröffentlichen. –

0

Ich bin nicht sicher, was Sie in genau ausgeführt werden, aber das ist etwas, das ich zusammen auf Informationen basieren stellen https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-2/

Vielleicht mit meinem Code vergleichen und sehen, was anders sein könnte

public string CreateSharedAccessSignature(string blobUri, int timeout, TimeUnitType timeUnit) 
    { 
     try 
     { 
      var uri = new Uri(blobUri); 
      var cloudBlob = _context.CloudBlobClient.GetBlobReferenceFromServer(uri); 

      if (!cloudBlob.Exists()) 
      { 
       throw new StorageException("Blob does not exist"); 
      } 

      var sasConstraints = new SharedAccessBlobPolicy 
      { 
       SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5), 
       Permissions = SharedAccessBlobPermissions.Read 
      }; 

      //The shared access signature will be valid immediately. 
      switch(timeUnit) 
      { 
       case TimeUnitType.Days: 
        sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddDays(timeout); 
        break; 
       case TimeUnitType.Hours: 
        sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(timeout); 
        break; 
       case TimeUnitType.Minutes: 
        sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(timeout); 
        break; 
       case TimeUnitType.Seconds: 
        sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddSeconds(timeout); 
        break; 
      } 

      //Generate the shared access signature on the blob, setting the constraints directly on the signature. 
      string sasBlobToken = cloudBlob.GetSharedAccessSignature(sasConstraints); 

      return cloudBlob.Uri + sasBlobToken; 
     } 
     catch(Exception ex) 
     { 
      //new RaygunClient().Send(ex); 
      throw; 
     } 
    }