Ejercicio: Uso de firmas de acceso compartido para delegar el acceso a Azure Storage
Azure Storage permite autorizar el acceso a archivos con una clave compartida, con una firma de acceso compartido (SAS) o mediante Microsoft Entra ID. Con una SAS, puede controlar lo que un cliente puede hacer con los archivos y durante cuánto tiempo.
El sistema de diagnóstico de imágenes de la empresa accede a las imágenes de los pacientes de forma interna a través de una clave compartida. Tiene que crear una API para permitir el acceso de terceros a las imágenes de diagnóstico. Va a crear una página de prueba en la aplicación web para ver cómo una SAS puede ayudar a conceder acceso seguro a los clientes de terceros.
En este ejercicio, creará una cuenta de almacenamiento y cargará algunas imágenes de pacientes de ejemplo. Implementará la aplicación web existente del equipo y comprobará que puede acceder al almacenamiento. El último paso consiste en agregar código de C# y JavaScript para generar un token de SAS a petición a fin de ver las imágenes de forma segura.
Creación de una cuenta de almacenamiento y carga de imágenes
Con Azure Cloud Shell, escriba el código siguiente para crear una cuenta de almacenamiento para las imágenes de los pacientes. El código genera un nombre de cuenta de almacenamiento.
export STORAGENAME=medicalrecords$RANDOM az storage account create \ --name $STORAGENAME \ --access-tier hot \ --kind StorageV2 \ --resource-group "<rgn>[sandbox resource group name]</rgn>"
Cree un contenedor en la cuenta de almacenamiento para almacenar las imágenes.
az storage container create \ --name patient-images \ --account-name $STORAGENAME \ --public-access off
Clone la aplicación web existente del equipo. Este repositorio contiene imágenes de ejemplo usadas por el equipo en las pruebas.
git clone https://github.com/MicrosoftDocs/mslearn-control-access-to-azure-storage-with-sas.git sas
Use el comando upload-batch de la CLI de Azure para cargar las imágenes en la cuenta de almacenamiento.
az storage blob upload-batch \ --source sas \ --destination patient-images \ --account-name $STORAGENAME \ --pattern *.jpg
Prueba del sistema de imágenes de diagnóstico de pacientes
Abra el archivo appsettings.json en el editor de código para poder agregar la cadena de conexión de la cuenta de almacenamiento.
code sas/appsettings.json
En Cloud Shell, escriba el código siguiente para obtener la cadena de conexión a la cuenta de almacenamiento.
az storage account show-connection-string --name $STORAGENAME
Debería ver una respuesta en este formato:
{ "connectionString": "DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=medicalrecords3215;AccountKey=UGLNuJWUBtodz+VbhhFcMwkzDpX49Wf7FxtuQDTOHhH+LpCtSQ2LBP0Ju8TQby5CeOt7DMYBgH45SX9yFwqPvA==" }
Copie el valor connectionString, incluidas las comillas.
En el editor de código, reemplace el valor ConnectionString
"[connection string]"
por la cadena que ha copiado.Copie el valor de
AccountName=
en el cuerpo de la cadena de conexión.Reemplace el valor del parámetro AccountName por el valor de nombre de cuenta que ha copiado.
Copie el valor de
AccountKey=
en el cuerpo de la cadena de conexión (no incluya las comillas). Asegúrese de incluir==
al final del valor.Reemplace el valor del parámetro AccountKey por el valor de clave de cuenta que ha copiado.
El archivo appsettings.json debe tener un aspecto similar a esta salida.
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "StorageAccount": { "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=medicalrecords3215;AccountKey=UGLNuJWUBtodz+VbhhFcMwkzDpX49Wf7FxtuQDTOHhH+LpCtSQ2LBP0Ju8TQby5CeOt7DMYBgH45SX9yFwqPvA==;EndpointSuffix=core.windows.net", "Container" : "patient-images", "AccountName":"medicalrecords3215", "AccountKey":"UGLNuJWUBtodz+VbhhFcMwkzDpX49Wf7FxtuQDTOHhH+LpCtSQ2LBP0Ju8TQby5CeOt7DMYBgH45SX9yFwqPvA==" } }
Presione Ctrl+S y después Ctrl+Q para guardar y cerrar el editor de código.
Abra un puerto para acceder a la aplicación web cuando se ejecuta en Cloud Shell.
curl -X POST http://localhost:8888/openPort/8000;
Este comando devuelve un valor
url
desde la que se puede acceder a la aplicación.{"message":"Port 8000 is open","url":"https://gateway11.northeurope.console.azure.com/n/cc-4016c848/cc-4016c848/proxy/8000/"}
Ejecute la aplicación.
cd sas dotnet run
Una vez compilada la aplicación, la consola de Cloud Shell muestra detalles similares al ejemplo siguiente.
Hosting environment: Development Content root path: /home/<yourusername>/sas Now listening on: https://localhost:8001 Now listening on: http://localhost:8000 Application started. Press Ctrl+C to shut down.
En un explorador, pegue la dirección URL devuelta por el comando cURL anterior. Asegúrese de incluir la barra diagonal (/) al final de la dirección.
La dirección URL debe tener este formato:
https://gateway11.northeurope.console.azure.com/n/cc-4016c848/cc-4016c848/proxy/8000/
.Si se le pide que inicie sesión, actualice la ventana del explorador. Aparece el sistema de imágenes de diagnóstico de pacientes de Lamna Healthcare.
Seleccione Get all patients (Obtener todos los pacientes) para ver una lista de todas las imágenes de la cuenta de almacenamiento.
Adición de código para crear una SAS
En Cloud Shell, presione Ctrl+C para detener la aplicación web.
Ahora se mejorará la clase PatientRecordController para crear una SAS a petición y devolverla al front-end de la aplicación web.
Escriba el código siguiente para abrir el archivo PatientRecordController.cs en el editor de código.
code Controllers/PatientRecordController.cs
Agregue el código siguiente a la parte inferior de la clase en el método
GET PatientRecord/patient-nnnnnn
.// GET PatientRecord/patient-nnnnnn/secure [HttpGet("{Name}/{secure}")] public PatientRecord Get(string name, string flag) { BlobClient blob = _container.GetBlobClient(name); return new PatientRecord { name=blob.Name, imageURI=blob.Uri.AbsoluteUri, sasToken=GetBlobSas(blob) }; }
Este método devuelve la imagen de paciente solicitada con una SAS que se puede usar para acceder a ella.
Agregue un método que crea la SAS para el blob.
// Build a SAS token for the given blob private string GetBlobSas(BlobClient blob) { // Create a user SAS that only allows reading for a minute BlobSasBuilder sas = new BlobSasBuilder { BlobContainerName = blob.BlobContainerName, BlobName = blob.Name, Resource = "b", ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(1) }; // Allow read access sas.SetPermissions(BlobSasPermissions.Read); // Use the shared key to access the blob var storageSharedKeyCredential = new StorageSharedKeyCredential( _iconfiguration.GetValue<string>("StorageAccount:AccountName"), _iconfiguration.GetValue<string>("StorageAccount:AccountKey") ); return '?' + sas.ToSasQueryParameters(storageSharedKeyCredential).ToString(); }
Este método usa el objeto
BlobClient
pasado para crear un elementoBlobSasBuilder
a fin de generar una SAS de solo lectura que expira en un minuto.Presione Ctrl+S para guardar el archivo y después Ctrl+Q para salir del editor.
Adición de código para usar la SAS
Ahora agregará código a la página web para solicitar la SAS para la imagen.
Escriba el comando siguiente para editar la página external.cshtml.
code Pages/external.cshtml
Cerca del final del archivo, en el cliente de escucha de clic para
#btn-submit
, modifique la línea$.get
para agregar+ '/secure'
:$('#btn-submit').click(function(){ $('#result').empty(); $.get('api/PatientRecords/' + $('#patientID').val() + '/secure', function (data) { var imageURL = data.imageURI + $('#sasKey').val(); $('#result').html('<img id="patientScan" class="alert alert-success" src="' + imageURL + '" alt="patient scan" onerror="this.classList.remove(\'alert-success\'); this.classList.add(\'alert-danger\')"//>'); }, 'json'); });
Debajo de la función del cliente de escucha de clic
#btn-submit
, en la parte inferior del archivo, encima de la etiqueta</script>
, agregue el código siguiente:$('#btn-getKey').click(function(){ $.get('api/PatientRecords/' + $('#patientID').val() + '/secure', function (data) { $('#sasKey').val(data.sasToken); }, 'json'); });
Este código de jQuery agrega un cliente de escucha de clic en el botón
btn-getKey
. El código ejecuta una llamada Ajax a la nueva dirección URL segura para el archivo de imagen especificado. Cuando devuelve un valor, rellena el cuadro de entrada de la clave con la SAS.Presione Ctrl+S para guardar los cambios y después Ctrl+Q para salir del editor.
Prueba de los cambios
Ejecute la aplicación actualizada.
dotnet run
En el explorador, actualice la pestaña del sitio web. Seleccione Get all patients (Obtener todos los pacientes) y, después, copie uno de los nombres de archivo de imagen.
En el menú de la parte superior de la página web, seleccione External companies (Empresas externas).
Pegue el nombre de archivo en el campo Patient image filename (Nombre del archivo de imagen de paciente).
Seleccione View scan (Ver examen). No se puede acceder a la imagen de examen de pacientes porque no se ha creado una SAS.
Nota:
Si ve la consola en el explorador, verá que el servidor web ha devuelto un mensaje con el código de error 404.
Seleccione Obtener clave, lo que debe rellenar el campo Clave con una SAS.
Seleccione View scan (Ver examen). Debería aparecer la imagen de diagnóstico del paciente.
En el explorador, haga clic con el botón derecho en la imagen y copie su dirección.
Abra una nueva pestaña del explorador, pegue la dirección de la imagen copiada en la barra de direcciones y presione Entrar. Si ha transcurrido más de un minuto desde que ha creado la SAS, verá un mensaje de error. Si ha pasado menos de un minuto, debería mostrarse la imagen.
Nota:
Es posible que tenga que actualizar la página.
<Error> <Code>AuthenticationFailed</Code> <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly, including the signature. RequestId:03eda893-f01e-0028-2d73-c5c947000000 Time:2021-01-07T16:02:55.3752851Z</Message> <AuthenticationErrorDetail>Signed expiry time [Tue, 07 Jan 2021 16:02:00 GMT] must be after signed start time [Tue, 07 Jan 2021 16:02:55 GMT]</AuthenticationErrorDetail> </Error>
Nota:
Para ver este mensaje de error en algunos exploradores, es posible que tenga que abrir una nueva ventana del explorador que no haya almacenado la imagen en caché.
En Cloud Shell, presione Ctrl+C para salir de la aplicación web.