2012-05-04 4 views
5

Ich versuche, auf einen Blob zuzugreifen, der in einem privaten Container in Windows Azure gespeichert ist. Der Container hat eine Shared Access-Signatur, aber wenn ich versuche, auf den Blob zuzugreifen, erhalte ich eine StorgeClientException "Server konnte die Anforderung nicht authentifizieren. Stellen Sie sicher, dass der Autorisierungsheader korrekt gebildet ist und die Signatur enthält" .So verwenden Sie SharedAccessSignature für den Zugriff auf Blobs

Der Code, der den Container erstellt und hochgeladen das Blob wie folgt aussieht:

// create the container, set a Shared Access Signature, and share it 

// first this to do is to create the connnection to the storage account 
// this should be in app.config but as this isa test it will just be implemented 
// here: 
// add a reference to Microsoft.WindowsAzure.StorageClient 
// and Microsoft.WindowsAzure.StorageClient set up the objects 
//storageAccount = CloudStorageAccount.DevelopmentStorageAccount; 

storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["ConnectionString"]); 
blobClient = storageAccount.CreateCloudBlobClient(); 

// get a reference tot he container for the shared access signature 
container = blobClient.GetContainerReference("blobcontainer"); 
container.CreateIfNotExist(); 

// now create the permissions policy to use and a public access setting 
var permissions = container.GetPermissions(); 
permissions.SharedAccessPolicies.Remove("accesspolicy"); 
permissions.SharedAccessPolicies.Add("accesspolicy", new SharedAccessPolicy 
                   { 
                    // this policy is live immediately 
                    // if the policy should be delatyed then use: 
                    //SharedAccessStartTime = DateTime.Now.Add(T); where T is some timespan 
                    SharedAccessExpiryTime = 
                     DateTime.UtcNow.AddYears(2), 
                    Permissions = 
                     SharedAccessPermissions.Read | SharedAccessPermissions.Write 
                   }); 

// turn off public access 
permissions.PublicAccess = BlobContainerPublicAccessType.Off; 

// set the permission on the ocntianer 
container.SetPermissions(permissions); 

var sas = container.GetSharedAccessSignature(new SharedAccessPolicy(), "accesspolicy"); 


StorageCredentialsSharedAccessSignature credentials = new StorageCredentialsSharedAccessSignature(sas); 
CloudBlobClient client = new CloudBlobClient(storageAccount.BlobEndpoint, 
              new StorageCredentialsSharedAccessSignature(sas)); 

CloudBlob sasblob = client.GetBlobReference("blobcontainer/someblob.txt"); 
sasblob.UploadText("I want to read this text via a rest call"); 

// write the SAS to file so I can use it later in other apps 
using (var writer = new StreamWriter(@"C:\policy.txt")) 
{ 
    writer.WriteLine(container.GetSharedAccessSignature(new SharedAccessPolicy(), "securedblobpolicy")); 
} 

Der Code wie folgt den Blob zu lesen sieht Ich habe versucht, zu verwenden:

// the storace credentials shared access signature is copied directly from the text file "c:\policy.txt" 
CloudBlobClient client = new CloudBlobClient("https://my.azurestorage.windows.net/", new StorageCredentialsSharedAccessSignature("?sr=c&si=accesspolicy&sig=0PMoXpht2TF1Jr0uYPfUQnLaPMiXrqegmjYzeg69%2FCI%3D")); 

CloudBlob blob = client.GetBlobReference("blobcontainer/someblob.txt"); 

Console.WriteLine(blob.DownloadText()); 
Console.ReadLine(); 

ich kann Machen Sie die oben genannten Arbeiten, indem Sie die Kontoanmeldeinformationen hinzufügen, aber genau das versuche ich zu vermeiden. Ich möchte nichts so empfindlich wie meine Kontoanmeldeinformationen nur sitzen da draußen und ich habe keine Ahnung, wie Sie die Signatur in die Client-App erhalten, ohne die Kontoanmeldeinformationen zu haben.

Jede Hilfe wird sehr geschätzt.

Antwort

1

Ist "mein.azurestorage.windows.net" nur ein Tippfehler? Ich würde etwas dort erwarten, wie "https: // Konto .blob.core.windows.net". Der Code ähnelt dem Code in http://blog.smarx.com/posts/shared-access-signatures-are-easy-these-days, der funktioniert.

+0

my.azurestorage.windows.net ist da, da es keine Notwendigkeit gibt, Kontoinformationen öffentlich zu machen. Der Code ähnelt dem Code in dem Blog, auf den Sie verwiesen haben. Der Code funktioniert zwar in gewissem Umfang, er ermöglicht jedoch keinen anonymen Zugriff auf einen Blob mit der gemeinsamen Zugriffssignatur. Das ist das Problem! – crunchy

+0

Aber natürlich endet Ihr tatsächlicher Wert dort in '.blob.core.windows.net', oder? (Und das Präfix ist der Name Ihres Speicherkontos?) – smarx

+0

der Wert in der tatsächlichen Anwendung ist die Adresse für den Container. Ich habe meinen Code gerade nicht geöffnet, aber was da drin ist, ist genau, da ich auf die Container und Blobs zugreifen kann, wenn ich die Kontoanmeldeinformationen zur Verfügung stelle. Ich bin mir immer noch nicht sicher, warum die angegebene Richtlinie nicht die richtigen Werte zurückgibt, aber es funktioniert jetzt. Danke für die Eingabe. – crunchy

3

Warum das?

writer.WriteLine(container.GetSharedAccessSignature(new SharedAccessPolicy(), "securedblobpolicy")); 

und nicht die sas String Schreiben Sie bereits erstellt?

Es ist spät und ich könnte leicht etwas vermissen, aber es scheint, dass Sie nicht die gleiche Zugriffssignatur speichern, die Sie verwenden, um die Datei an erster Stelle zu schreiben.

Auch vielleicht nicht relevant hier, aber ich glaube, es gibt eine Grenze für die Anzahl der Container-weiten Richtlinien, die Sie haben können. Laden Sie mehrere Dateien mit demselben Code in denselben Container hoch und erstellen Sie jedes Mal einen neuen Container?

Im Allgemeinen denke ich, es wäre besser, einen sas für einen einzelnen Blob zu der Zeit anzufordern, wenn Sie es mit einer kurzen Ablaufzeit benötigen.

+0

container.GetSharedAccessSignature (new SharedAccessPolicy(), "securedblobpolicy")) gibt die sas-Zeichenkette aus dem Container zurück (oder zumindest geht es mir so, ich könnte falsch liegen.) – crunchy

+0

Meine Güte, das war schmerzhaft. Offensichtlich habe ich nicht den gleichen Schlüssel abgerufen, als ich die GetSharedAccessSignature-Methode verwendet habe. Danke, dass du das auf Mark aufmerksam gemacht hast.Jetzt muss ich mich nur noch wie ein Idiot verhalten :) – crunchy

+1

Ich bin froh, dass ich helfen kann - und fühle mich nicht schlecht - wir machen es alle! –