2012-05-04 5 views
5

Sto tentando di accedere a un BLOB archiviato in un contenitore privato in Windows Azure. Il contenitore ha una firma Shared Access ma quando provo per accedere al blob ho uno StorgeClientException "Server non è riuscito a autenticare la richiesta. Assicurarsi che l'intestazione di autorizzazione è formato compreso correttamente la firma".Come utilizzare SharedAccessSignature per accedere ai BLOB

Il codice che ha creato il contenitore e caricato il blob si presenta così:

// 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")); 
} 

Il codice che ho cercato di usare per leggere il blob si presenta così:

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

posso fare il lavoro di cui sopra aggiungendo le credenziali dell'account ma è esattamente quello che sto cercando di evitare. Non voglio che qualcosa come sia sensibile come le credenziali del mio account e non ho idea di come ottenere la firma nell'app client senza le credenziali dell'account.

Qualsiasi aiuto è molto apprezzato.

risposta

1

"my.azurestorage.windows.net" è solo un refuso? Mi aspetterei qualcosa come "https: // account .blob.core.windows.net".

In caso contrario, il codice sembra piuttosto simile al codice a http://blog.smarx.com/posts/shared-access-signatures-are-easy-these-days, che funziona.

+0

my.azurestorage.windows.net è lì perché non è necessario rendere pubbliche le informazioni sull'account. E il codice potrebbe sembrare abbastanza simile al codice nel blog a cui si fa riferimento, e funziona in misura limitata, ma non consente l'accesso anonimo a un blob con l'uso della firma di accesso condiviso. Questo è il problema! – crunchy

+0

Ma per essere sicuro, il tuo valore attuale finisce in '.blob.core.windows.net', giusto? (E il prefisso è il nome del tuo account di archiviazione?) – smarx

+0

il valore nell'applicazione reale è l'indirizzo del contenitore. Al momento non ho ancora aperto il mio codice, ma quello che ho è preciso perché posso accedere ai contenitori e ai BLOB quando fornisco le credenziali dell'account. Non sono ancora sicuro del motivo per cui la politica denominata non ha restituito i valori corretti, ma funziona ora. Grazie per l'input. – crunchy

3

Perché questo?

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

e non si scrive la stringa sas già creata?

È tardi e ho potuto facilmente essere manca qualcosa, ma sembra che si potrebbe non essere salvando la stessa firma di accesso che si sta utilizzando per scrivere il file, in primo luogo.

Inoltre forse non rilevante qui, ma credo che ci sia un limite al numero di politiche a livello di contenitore che si può avere. Stai caricando più file nello stesso contenitore con questo codice e creando ogni volta un nuovo contenitore sas?

In generale penso che sarebbe meglio chiedere una sas per un blob individuo nel momento in cui ne ha bisogno con un breve periodo di scadenza.

+0

container.GetSharedAccessSignature (nuova SharedAccessPolicy(), "securedblobpolicy")) sta tornando la stringa sas dal contenitore (o almeno questo è ciò che io presumo che sta facendo, potrei sbagliarmi.) – crunchy

+0

Accidenti, che è stato doloroso. Quindi apparentemente non stavo recuperando la stessa chiave quando ho usato il metodo GetSharedAccessSignature. Grazie per averlo fatto notare Mark.Ora devo solo sentirmi un pazzo :) – crunchy

+1

Felice di essere di aiuto - e non mi sento male - lo facciamo tutti! –