Azure Storage è tra i primi servizi nati all'interno della piattaforma Microsoft Azure ed è lo strumento principale che possiamo utilizzare se necessitiamo di depositare file in modo sicuro, affidabile, completamente gestito e performante.
I blob sono contenuti all'interno dei container e dispongono di un meccanismo di protezione semplice, ma allo stesso tempo molto potente. Quando ci ritroviamo a salvare file il cui accesso dev'essere regolato da policy particolari, l'unica scelta che abbiamo è di rendere il container privato e di conseguenza disporre dell'URI della risorsa non è più sufficiente per poterla scaricare o manipolare. Quello che otteniamo è un 404 che mette al riparo il file da qualsiasi uso inappropriato.
Se però disponiamo di una pagina HTML dove per esempio mostriamo una lista di immagini protette, dobbiamo temporaneamente dare accesso alle stesse e solo per l'utente corrente. Per raggiungere questo scopo, nell'elaborazione server side della risposta che genera il JSON o l'HTML, possiamo generare degli indirizzi temporanei così da permettere al browser di scaricare e visualizzare l'immagine. Questo è possibile grazie al fatto che gli URI possono contenere una firma, detta Shared Access Signature (SAS), che contiene al suo interno i permessi che l'utente ha sulla risorsa. Questa firma può essere generata solo avendo una delle due chiavi dello storage.
Utilizzando l'SDK di .NET, per esempio, possiamo ottenere il riferimento ad un CloudBlockBlob di nostro interesse e utilizzare il metodo GetSharedAccessSignature per ottenere una firma da porre in coda all'indirizzo originale, come mostrato nell'esempio.
// Credenziali account CloudStorageAccount account = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;...."); CloudBlobClient client = account.CreateCloudBlobClient(); // Ottengo il container CloudBlobContainer container = client.GetContainerReference("myContainer"); CloudBlockBlob blob = container.GetBlockBlobReference("myImage.png"); // Permessi e scadenza della policy var policy = new SharedAccessBlobPolicy() { SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-1), SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1), Permissions = SharedAccessBlobPermissions.Read }; string token = blob.GetSharedAccessSignature(policy); string uri = blob.Uri + token;
La policy che viene creata determina i permessi sul file e gli intervalli temporali di validità, i quali verranno inseriti nella query string, insieme alla firma, producendo un indirizzo simile a myContainer/myImage.png?sv=2018-03-28&sr=b&sig=?&st=2019-06-24T21%3A07%3A10Z&se=2019-06-24T21%3A09%3A10Z&sp=r. L'aspetto interessante è che per produrre questa firma non è necessario nessuna chiamata server to server. L'operazione è immediata e può essere effettuata per ogni singola immagine. In questo modo possiamo anche permetterci di generare token dalla validità molto breve. Se l'utente aggiorna la pagina possiamo poi generare ancora nuovi token dando URI che dopo un minuto perderanno di utilità.
Infine, se disponiamo già dell'indirizzo completo, possiamo usare il costruttore di CloudBlockBlob dando l'intero indirizzo e passando le credenziali, al fine di poter invocare sempre GetSharedAccessSignature.
// Ottengo il blob CloudBlockBlob blob = new CloudBlockBlob(new Uri("https://myStorage.blob.core.windows.net/myContainer/myImage.png"), account.Credentials);
L'unica cosa da prestare attenzione, se generiamo molti indirizzi, è quella di evitare quei metodi che fanno ricorso a chiamate verso lo storage, come per esempio GetBlobReferenceFromServerAsync.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Eseguire un metodo asincrono dopo il set di una proprietà in Blazor 8
Usare un KeyedService di default in ASP.NET Core 8
Creare un'applicazione React e configurare Tailwind CSS
Sostituire la GitHub Action di login su private registry
Utilizzare gli snapshot con Azure File shares
Usare Refit e Polly in Blazor per creare client affidabili e fortemente tipizzati
Utilizzare domini personalizzati gestiti automaticamente con Azure Container Apps
Eseguire una query su SQL Azure tramite un workflow di GitHub
Come migrare da una form non tipizzata a una form tipizzata in Angular
Applicare il versioning ai nostri endpoint ASP.NET Core Minimal API
Migrare una service connection a workload identity federation in Azure DevOps
Controllare gli accessi IP alle app con Azure Container Apps