2014-07-15 15 views
5

Sto lavorando a una soluzione in cui un numero limitato di utenti autenticati deve avere accesso completo a un set di contenitori di archiviazione BLOB di Azure. Al momento ho implementato un sistema con accesso pubblico e mi chiedo se è necessario complicare ulteriormente il sistema o se questo sistema sia sufficientemente sicuro. Ho analizzato brevemente come funziona Shared Access Signatures (SAS), ma non sono sicuro che sia davvero necessario, e quindi chiedo spiegazioni. L'obiettivo è consentire solo agli utenti autenticati di avere pieno accesso ai contenitori BLOB e ai loro contenuti.Opzioni di sicurezza di archiviazione BLOB di Azure in MVC

L'attuale sistema imposta le autorizzazioni nel modo seguente (C#, MVC):

// Retrieve a reference to my image container 
myContainer = blobClient.GetContainerReference("myimagescontainer"); 

// Create the container if it doesn't already exist 
if (myContainer.CreateIfNotExists()) 
{ 
    // Configure container for public access 
    var permissions = myContainer.GetPermissions(); 
    permissions.PublicAccess = BlobContainerPublicAccessType.Container; 
    myContainer.SetPermissions(permissions); 
} 

Di conseguenza, tutte le macchie sono completamente accessibili fino a quando si ha l'URL completo, ma non sembra essere possibile elencare le macchie nel contenitore direttamente tramite l'URL:

// This URL allows you to view one single image directly: 
'https://mystorageaccount.blob.core.windows.net/mycontainer/mycontainer/image_ea644f08-3263-4a7f-9be7-bc42efbf8939.jpg' 

// These URLs appear to return to nothing but an error page: 
'https://mystorageaccount.blob.core.windows.net/mycontainer/mycontainer/' 
'https://mystorageaccount.blob.core.windows.net/mycontainer/' 
'https://mystorageaccount.blob.core.windows.net/' 

io non lo trovo un problema che autenticati agli utenti di condividere URL completi, consentendo l'accesso pubblico ad una singola immagine; tuttavia, nessuno tranne gli utenti autenticati dovrebbe essere in grado di elencare, sfogliare o accedere direttamente ai contenitori per recuperare altre immagini.

La mia domanda diventa quindi se dovrei proteggere ulteriormente il sistema, ad esempio utilizzando SAS, quando ora sembra funzionare come previsto, o lasciare il sistema così com'è. Potresti capire che mi piacerebbe non complicare il sistema se non strettamente necessario. Grazie!

La soluzione che ho finito per usare è stato dato seguito :)

risposta

2

Se si utilizza un contenitore pubblico, allora non siete veramente limitare l'accesso agli utenti autenticati.

Se la specifica diceva che "solo gli utenti autenticati dovrebbero avere accesso", personalmente ritengo inaccettabile l'utilizzo di un contenitore pubblico. SAS non è molto difficile - le librerie fanno la maggior parte del lavoro.

BTW: il formato da list the items in a container è: https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list

+0

Vedendo ora quanto è facile elencare il contenuto di un contenitore pubblico, sono assolutamente d'accordo con te. Grazie! –

2

Se si desidera solo la vostra autenticazione. gli utenti che hanno accesso devono rendere privato il contenitore. Altrimenti sarà pubblico ed è solo questione di tempo che qualcun altro arrivi al contenuto "quasi privato" e tu come sviluppatore ti vergogni.

Metodo 1: inviare un collegamento al proprio utente autorizzato. In questo caso fornisci un collegamento SAS all'utente e scarica direttamente il suo contenuto dal blob. È necessario generare firme SAS con una finestra di accesso breve in modo che gli utenti possano scaricare i contenuti e scaricarli/aprirli e, una volta usciti dal sito, il collegamento scadrà e il contenuto non sarà più disponibile. Questo è nel caso in cui inviano accidentalmente il collegamento via cavo e qualcun altro arriva al contenuto privato in seguito.

Approccio 2: il server Web riceve il contenuto e lo consegna ai clienti In questo caso, solo l'app Web avrà accesso e non sarà necessario generare firme SAS. Si restituisce FileContentResult (nel caso di MVC) e si è pronti. Il rovescio della medaglia è che il tuo server web deve scaricare il file prima di darlo al client - doppio traffico. Qui devi gestire attentamente il download di Blob-> Web perché se 3 utenti tentano di scaricare un file da 200 MB insieme e lo stai archiviando nella RAM, sarà esaurito.

+0

Credo che tu abbia ragione: vorrei semplicemente che i miei contenitori fossero privati. Come si fa a rendere privato un container? Basta impostare PublicAccess su Off? La ringrazio per la risposta. –

+1

I contenitori BLOB in Azure sono privati ​​per impostazione predefinita. _Per impostazione predefinita, è possibile accedere a un contenitore e a tutti i BLOB al suo interno solo dal proprietario dell'account di archiviazione. Se si desidera consentire agli utenti anonimi di leggere le autorizzazioni per un contenitore e i relativi BLOB, è possibile impostare le autorizzazioni del contenitore per consentire l'accesso pubblico. Gli utenti anonimi possono leggere i BLOB all'interno di un contenitore accessibile pubblicamente senza autenticare la richiesta. Leggi completamente qui [qui] (http://msdn.microsoft.com/en-us/library/azure/dd179354.aspx) –

+0

Quindi, in altri parole, impostando PublicAccess.Off - o non impostando * qualsiasi * autorizzazione a tutti - fornirai un contenitore privato. Sto capendo correttamente? –

2

Quindi, ecco cosa ho fatto. Grazie a Neil e Ognyan per avermi portato lì.

Esso funziona come seguenti:

  • tutte le immagini sono private, e non può essere visualizzato affatto senza avere un valido SAS
  • Aggiunta, eliminazione e la modifica delle macchie sono realizzati all'interno del controllore stesso, tutto in privato Nessun SAS o ulteriori procedure sono necessarie per queste attività.
  • Quando un'immagine deve essere visualizzata all'utente (anonima o autenticata), una funzione genera un SAS con una scadenza rapida è che consente semplicemente al browser di scaricare l'immagine (o blob), alla generazione e all'aggiornamento delle pagine, ma non copiare/incollare un URL utile all'esterno.

ho messo esplicitamente i permessi contenitore per privato (questa è anche l'impostazione di default, secondo Ognyan):

// Connect to storage account 
... 

// Retrieve reference to a container. 
myContainer= blobClient.GetContainerReference("mycontainer"); 

// Create the container if it doesn't already exist. 
if (myContainer.CreateIfNotExists()) 
{ 
    // Explicitly configure container for private access 
    var permissions = myContainer.GetPermissions(); 
    permissions.PublicAccess = BlobContainerPublicAccessType.Off; 
    myContainer.SetPermissions(permissions); 
} 

Poi più tardi, quando si vuole visualizzare l'immagine, ho aggiunto un stringa di SAS nel percorso di memorizzazione originale del blob:

public string GetBlobPathWithSas(string myBlobName) 
{ 
    // Get container reference 
    ... 

    // Get the blob, in my case an image 
    CloudBlockBlob blob = myContainer.GetBlockBlobReference(myBlobName);   

    // Generate a Shared Access Signature that expires after 1 minute, with Read and List access 
    // (A shorter expiry might be feasible for small files, while larger files might need a 
    // longer access period) 
    string sas = myContainer.GetSharedAccessSignature(new SharedAccessBlobPolicy() 
    { 
     SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1), 
     Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.List 
    }); 
    return (blob.Uri.ToString() + sas).ToString(); 
} 

ho poi chiamato il GetBlobPathWithSas() -funzione da con nella vista rasoio, in modo che ogni aggiornamento della pagina darebbe un valido percorso di + sas per la visualizzazione dell'immagine:

<img src="@GetPathWithSas("myImage")" /> 

In generale, ho trovato questo utile riferimento:

http://msdn.microsoft.com/en-us/library/ee758387.aspx

Speranza questo aiuta qualcuno!

+1

Assicurati di inserire il codice "if (myContainer.CreateIfNotExists()) ...." in un singleton o altro per eseguirlo una volta all'avvio. Altrimenti pagherai il viaggio di rigore su ogni richiesta. –

3

io uso "approccio 2" di Ognyan Dimitrov per servire piccoli file PDF memorizzati in un contenitore blob privata ("No pubblico accesso in lettura") all'interno di una finestra del browser come questo:

public ActionResult ShowPdf() 
{ 
    string fileName = "fileName.pdf"; 

    var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); 
    var blobClient = storageAccount.CreateCloudBlobClient(); 
    var container = blobClient.GetContainerReference("containerName"); 
    var blockBlob = container.GetBlockBlobReference(fileName); 

    Response.AppendHeader("Content-Disposition", "inline; filename=" + fileName); 
    return File(blockBlob.DownloadByteArray(), "application/pdf"); 
} 

con file di configurazione

<configuration> 
    <appSettings> 
     <add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key" /> 
    </appSettings> 
</configuration> 

... che funziona perfettamente per me!

Problemi correlati