ÍNDICE
1. INTRODUCCIÓN
2. CASO PRÁCTICO
2.1. Creación de la cuenta de almacenamiento y del contenedor
2.2. Creación de la aplicación API
2.3. Creación de la aplicación cliente
2.4. Ejecución de las aplicaciones API y cliente
3. CONCLUSIÓN

1. INTRODUCCIÓN

Presentación del problema

En este post se va a mostrar cómo usar permisos SAS en Azure Blob Storage para restringir el acceso a Blob Storage con la clave SAS (Shared Access Signatures), solo a aquellas aplicaciones clientes que tenga dicha clave. La clave SAS será proporcionada, a través de un token con permisos SAS, por una aplicación API que estará en medio de Blob Storage y la aplicación cliente. Con los permisos SAS la aplicación cliente podrá realizar sobre blobs (archivos de tipos diferentes como imágenes, videos, documentos de texto, etc) las acciones de listar, leer y escribir, pero no eliminarlos (porque se quiere restringir este permiso).

Puntos importantes

Para entender el problema es importante entender primero qué es Azure Blob Storage, y después qué es SAS y los permisos SAS. Por un lado, Azure Blob Storage (almacenamiento de blobs) es una solución de almacenamiento en la nube optimizado para almacenar cantidades masivas de datos no estructurados (es decir, que no cumplen un modelo de datos o definición concreta) como texto o datos binarios (imágenes, videos, audio, etc).

Blob Storage ofrece tres tipos de recursos: la cuenta de almacenamiento, necesaria no solo para tener acceso a esta solución de almacenamiento, sino también a los demás tipos; contenedores en la cuenta, y blobs en un contenedor.
Fuente: Introducción a Azure Blob Storage

Por otro, SAS (firma de acceso compartido) ofrece una manera de conceder acceso limitado a los objetos de la cuenta de almacenamiento a otros clientes sin exponer la clave de cuenta. El punto clave de usar SAS es que es una forma segura de compartir los recursos de almacenamiento sin poner en peligro las claves de cuenta.

Una SAS le ofrece control granular el tipo de acceso que se concede a los clientes que tienen la SAS, como por ejemplo: intervalo durante el que la SAS es validad; permisos concedidos por la SAS (ej: conceder permisos de lectura y escritura pero no de eliminación); dirección IP opcional o un intervalo de direcciones IP de las que Azure Storage aceptará la SAS; protocolo a través del cual Azure Storage aceptará la SAS (ej: restringir el acceso mediante HTTPS).
Fuente: Uso de firmas de acceso compartido (SAS)

Finalmente, en base a lo anterior se concluye que los permisos SAS son un tipo de control de acceso sobre las aplicaciones clientes que tiene acceso a la SAS, de modo que, si el cliente no tiene concedido un determinado permiso, no va a poder realizar la acción que restringe.

Un escenario común en el que es útil una SAS es un servicio en el que los usuarios leen y escriben sus propios datos en la cuenta de almacenamiento. Uno de los dos patrones de diseño existentes, y que se desarrolla en el presente post, consiste en que mediante una clave SAS se puede tener las claves en una tercera aplicación, la cual genera un Token de acceso a la cuenta de Azure Storage. Dicha clave de acceso es temporal y administra los permisos de acceso a la cuenta, por lo que la aplicación no tendrá nunca acceso a la cuenta Azure Storage completa, solamente a lo que se le desee limitar.

SasBlobStorage-PatronDiseño
SAS Blob Storage. Patrón de diseño

Resolución del problema

Para resolver el problema se va a crear dos aplicaciones. La primera aplicación es una aplicación web ASP.NET Web API que contendrá la clave SAS con permisos(permisos SAS) que da acceso a diferentes formas de almacenamiento de Azure, en este caso, a Azure Blob Storage. Estos permisos estarán incluidos en el token de acceso a la API, necesario para establecer conexión entre la API y una aplicación cliente de la misma.

Por su parte, la segunda aplicación es una aplicación web ASP.NET MVC, lacual hará de cliente de la API, es decir, es quien consume la API para obtener el token con los permisos SAS y acceder a los recursos almacenados en Azure Blob Storage. La aplicación cliente tiene los permisos para listar, leer y escribir blobs, pero no eliminarlos.

2. CASO PRÁCTICO

2.1. Creación de la cuenta de almacenamiento y del contenedor

Creación de la cuenta de almacenamiento

1. En el portal de Azure, se crea una cuenta de almacenamiento con un nombre único, en este caso, “cuentablobstorageamsl” porque al estar en la nube los nombres no puede repetirse. Se cumplimenta los campos obligatorios, en este caso, con los siguientes valores: campo suscripción (con “Azure for Students”), grupo de recursos (con “recursostajamar”) y localización (con “West Europe”, localización más cercana al lugar de residencia). Los demás campos se deja con los valores por defecto. Clic en Review + create.

SasBlobStorage-Azure-CreacionCuenta
SAS Blob Storage. Azure: Creación de cuenta de almacenamiento

2. Aparecerá una venta con los datos a revisar y si esta todo correcto, clic en Create para que se cree la cuenta de almacenamiento.

3. Una vez creada la cuenta de almacenamiento, se podrá ver los tipos de servicios de almacenamiento disponibles: Blobs, Files, Tables y Queues. El servicio que nos interesa es Blobs.

SasBlobStorage-Azure-ServiciosStorage
SAS Blob Storage. Azure: Servicios de almacenamiento

Creación del contenedor

4. Una vez dentro del servicio de Blobs, se puede crear un nuevo contenedor,que es una carpeta donde se almacenarán blobs. Para ello, basta con hacer clic en el botón “+” y asignarle un nombre que estar en minúsculas, en este caso, se llamará “contenedorblobs”. El campo Public access level se deja con el valor por defecto de “Private (no anonymous access)”. Clic en Ok para finalizar la creación.

SasBlobStorage-Azure-CreacionContenedor
SAS Blob Storage. Azure: Creación del contenedor

2.2. Creación de la aplicación API

Creación de la API

5. Una vez que se tiene en Azure la cuenta de almacenamiento y dentro de la misma un contenedor, desde Visual Studio se procede a crear un proyecto Web API de tipo ASP.NET Web Application (.NET Framework).

SasBlobStorage-API-Creacion
SAS Blob Storage. API: Creación de la aplicación Web API

6. En el proyecto se procede a instalar los siguientes paquetes NuGet: WindowsAzure.Storage, que permite usar el almacenamiento, y Microsoft.Azure.ConfigurationManager,que permite acceder a las claves de mi cuenta de almacenamiento.

SasBlobStorage-API-PaquetesNuGet
SAS Blob Storage. API: Instalación de paquetes NuGet

Modificación del archivo “Web.config”

7. En el portal de Azure, hay que dirigirse a la cuenta de almacenamiento, clic en la opción Access keys y se copia la Connection string de la key1 para posteriormente usarla en el archivo “Web.config”.

SasBlobStorage-Azure-ConnectionString
SAS Blob Storage. Azure: Cadena de conexión a la cuenta de almacenamiento

8. En el archivo “Web.config” de la aplicación Web API se tiene que añadir la cadena de conexión hacia nuestra cuenta de almacenamiento copiada en el paso anterior. Dentro de la etiqueta <appSettings> se añade la etiqueta <add>, la cual tendrá en su atributo key el nombre de nuestra cuenta de almacenamiento y en su atributo value se pega la cadena de conexión. Con la cadena de conexión la API tendrá acceso directo a nuestra cuenta.

SasBlobStorage-API-WebConfig
SAS Blob Storage. API: Adición de la cadena de conexión en el «Web.config»

Creación del controlador “TokenController.cs

9. Una vez que se tiene conexión a la cuenta de almacenamiento, se crea en la carpeta Controllers del proyecto API el controlador “TokenController.cs”.

El controlador tendrá dos métodos: el primero, RecuperarContenedor() será el encargado de recuperar el contenedor. Para ello, obtiene las keys (claves) de acceso a la cuenta a partir de la cadena de conexión “cuentablobstorageamsl” puesta en el “Web.config”. Con esas claves se puede instanciar la cuenta (CloudStorageAccount account) y con dicha instancia se puede crear un cliente (CloudBlobClient client). El cliente permitirá tener acceso al contenedor e instanciarlo (CloudBlobContainer container). Finalmente, el método devuelve el contenedor.

El segundo método, Get(), a partir del método RecuperarContenedor(), será el encargado de devolver la URI de contenedor + el token de acceso a la cuenta con permisos SAS sobre los blobs de la cuenta. Para establecer los permisos se crea la instancia de SAS (SharedAccessBlobPolicy permisosSas) y con ella se puede establecer en sus propiedades el tiempo de expiración de la SAS y sus permisos. Una vez establecido los permisos (junto con el tiempo de expiración) se obtiene el token.

A continuación, se muestra el código completo:

SasBlobStorage-API-TokenController.cs-ConPermisos
SAS Blob Storage. API: Creación de «TokenController.cs» con pemisos SAS

Modificación de la clase “WebApiConfig.cs”

10. En la carpeta App_Start se localiza la clases “WebApiConfig.cs” donde se quita el formato XML en el que se muestra los resultados que da la API para que consuma la aplicación cliente, por tanto el único formato en el que muestra los resultados será JSON.

SasBlobStorage-API-WebApiConfig.cs
SAS Blob Storage. API: Modificación de «WebApiConfig.cs»

Ejecución de la API

11. Finalmente, se ejecuta la API y accediendo a la ruta (http://localhost:51309/api/Token) se tendría el token de acceso a la cuenta de almacenamiento con permisos SAS.

SasBlobStorage-API-Ejecucion
SAS Blob Storage. API: Ejecución de la API para mostrar el token de acceso

2.3. Creación de la aplicación cliente

Creación del cliente

12. Una vez que se tiene creada y en funcionamiento la aplicación API, desde Visual Studio se procede a crear un proyecto Web MVC de tipo ASP.NET Web Application (.NET Framework).

SasBlobStorage-Cliente-Creacion
SAS Blob Storage. Cliente: Creación de la aplicación web cliente MVC

13. En el proyecto se procede a instalar el paquete NuGet: WindowsAzure.Storage, que permite usar el almacenamiento.

SasBlobStorage-Cliente-PaquetesNuGet
SAS Blob Storage. Cliente: Instalación del paquete NuGet

Creación de la carpeta Repositories y la clase “RepositoryBlobs.cs”

14. En el proyecto se crea la carpeta Repositories y dentro la clase “RepositoryBlobs.cs”, que es donde se realizará la lógica de acceso a la API para así obtener el token de acceso al almacenamiento con los permisos sobre los blobs (método GetTokenAcceso()), y la lógica para trabajar con el contenedor y sus blobs a partir del token.

Lo primero es hacer el método constructor de la clase RepositoryBlobs() donde se recupera el token en una variable llamada key y a partir de ella se recupera el contenedor sobre el cual se va a trabajar.

Después, se procede con la lógica para trabajar con el contenedor y sus blobs, la cual se realiza en los métodos: GetContainerName(), devuelve el nombre del contenedor; GetBlobs(), devuelve la colección de blobs del contenedor; SubirBlobs(), sube al contenedor “contenedorblobs” de Azure los blobs (imágenes, documentos de texto, etc), y  EliminarBlob(), elimina los blobs del contendor  devolviendo un mensaje de excepción si no tiene el permiso de eliminar que proporciona el token dado por la API.

A continuación, se muestra el código completo:

SasBlobStorage-Cliente-RepositoryBlobs.cs-1
SasBlobStorage-Cliente-RepositoryBlobs.cs-2
SasBlobStorage-Cliente-RepositoryBlobs.cs-3
SAS Blob Storage. Cliente: Creación de «RepositoryBlobs.cs»

Modificación del controlador “HomeController.cs”

15. Se modifica el controlador “HomeController.cs” añadiendo los métodos que nos interesan. Lo primero es instanciar la clase RepositoryBlobs en el método constructor HomeController() para tener disponible la lógica de acceso a la API y por tanto al token con permisos.

Después, se modifica el método Index(), que devolverá a la vista Index.cshtml el nombre del contenedor y la lista de blobs. Además se creará los métodos: SubirBlobs(), encargado de subir los blob a través de llamar al método del mismo nombre de la instancia repo (de la clase RepositoryBlobs) , y EliminarBlob(), encargado de eliminar blobs también llamando al método de la instancia repo. Estos dos métodos cuando se ejecutan redirigirán al método Index() tras realizar las acciones correspondientes.

A continuación, se muestra el código completo:

SasBlobStorage-Cliente-HomeController.cs
SAS Blob Storage. Cliente: Modificación de «HomeController.cs»

Creación de la vista “Index.cshtml”

16. Se procede a crear la vista “Index.cshtml”, que es donde se tendrá la parte visual de la aplicación cliente. La vista tendrá dos partes: la primera sirve para mostrar en una tabla todos los blobs que contiene el contendor con las características del blob como nombre, URL y tamaño y con la opción de eliminar cada blob; mientras que la segunda sirve para subir los blobs al contenedor de Azure.

A continuación, se muestra el código completo:

SasBlobStorage-Cliente-Index.cshtml-1
SasBlobStorage-Cliente-Index.cshtml-2
SAS Blob Storage. Cliente: Creación de «Index.cshtml»

2.4. Ejecución de las aplicaciones API y cliente

Ejecución de la API y el cliente con permiso de eliminar

17. Para poder ver el funcionamiento de la aplicación cliente es necesario que la API este en ejecución. Con las dos aplicaciones en ejecución, en la aplicación cliente se podrá subir blobs, mostrarlos en la tabla y eliminarlos (si tenemos en la API establecido el permiso, en este punto, sí). A continuación, se muestra el resultado:

SasBlobStorage-Cliente-EjecucionConPermisos
SAS Blob Storage. Cliente: Ejecución con permisos SAS

Ejecución de la API y el cliente sin permiso de eliminar

18. Si se comenta en la API el permiso de eliminar, la aplicación cliente ya no podrá eliminar los blobs.

SasBlobStorage-API-TokenController.cs-SinPermisos
SAS Blob Storage. API: Modificación de “TokenController.cs” quitando el permiso SAS de eliminar

19. Una vez comentado el permiso, si se ejecuta la aplicación cliente y se prueba a eliminar, el cliente no puede eliminar los blobs porque no tiene dicho permiso.

SasBlobStorage-Cliente-EjecucionSinPermisos
SAS Blob Storage. Cliente: Ejecución sin el permiso SAS de eliminar

3. CONCLUSIÓN

En resumen, los permisos SAS en Azure Blob Storage restrigen las acciones que se puede realizar sobre los blobs, por lo que aporta un nivel de seguridad más con respecto al que ya aporta la propia clave SAS proporcionada por la API. Si se quiere profundizar sobre SAS, en la web de Microsoft existe mayor información y ejemplos, mirar Uso de firmas de acceso compartido (SAS).

Entre los problemas que te puedes encontrar al resolver este tutorial están: poner los nombres de los contenedores en minúsculas, lo cual hay que tener muy en cuenta porque si se pone con alguna letra mayúscula la API no funciona; el quitar el formato XML en el que expone por defecto los datos la API y dejar formato JSON, o capturar la excepción que ocurre en la aplicación cliente cuando no se tiene un permiso, en este caso, el permiso de eliminar.

Espero que el seguimiento de este post os ayude a entender el tema y podáis profundizar en el mismo. ¡Saludos y hasta la próxima!

Autor: Andrés Marcelo Sánchez Luzuriaga
Curso: Microsoft MCSA Web Applications + Microsoft MCSD App Builder + Xamarin
Centro: Tajamar
Año académico: 2018-2019
Código / recursos utilizados / Otros datos de interés: GitHub / Introducción a Azure Blob Storage,Uso de firmas de acceso compartido (SAS)
Redes Sociales: LinkedIn

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.