Autenticación de aplicaciones Python en servicios de Azure durante el desarrollo local mediante entidades de servicio

Al crear aplicaciones en la nube, los desarrolladores necesitan depurar y probar aplicaciones en su estación de trabajo local. Cuando se ejecuta una aplicación en la estación de trabajo de un desarrollador durante el desarrollo local, esta debe autenticarse en los servicios de Azure que usa. En este artículo se explica cómo configurar objetos de entidad de servicio de aplicación dedicados que se usarán durante el desarrollo local.

Diagrama que muestra cómo una aplicación que se ejecuta en el desarrollador local obtiene la entidad de servicio de la aplicación de un archivo .env y, a continuación, usa esa identidad para conectarse a los recursos de Azure.

Las entidades de servicio de aplicaciones dedicadas para el desarrollo local permiten seguir el principio de privilegios mínimos durante el desarrollo de aplicaciones. Dado que los permisos tienen como ámbito exactamente lo que se necesita para la aplicación durante el desarrollo, se impide que el código de la aplicación acceda accidentalmente a un recurso de Azure destinado al uso por otra aplicación. Esto también impide que se produzcan errores cuando la aplicación se mueve al entorno de producción debido a un exceso de privilegios de la aplicación en el entorno de desarrollo.

Cuando la aplicación se registra en Azure, se configura una entidad de servicio de aplicación. Al registrar aplicaciones para el desarrollo local, se recomienda lo siguiente:

  • Crear registros de aplicaciones independientes para cada desarrollador que trabaje en la aplicación. Esto creará entidades de servicio de aplicación independientes para que las puedan usar cada desarrollador durante el desarrollo local y evitará la necesidad de que los desarrolladores compartan credenciales para una única entidad de servicio de aplicación.
  • Crear registros de aplicaciones independientes por cada aplicación. Esto limita los permisos de la aplicación solo a lo que necesita la aplicación.

Durante el desarrollo local, las variables de entorno se establecen con la identidad de la entidad de servicio de la aplicación. El SDK de Azure para Python lee estas variables de entorno y usa esta información para autenticar la aplicación en los recursos de Azure que necesita.

1: Registro de la aplicación en Azure

Los objetos de la entidad de servicio de la aplicación se crean con un registro de aplicación en Azure. Esto puede hacerse mediante Azure Portal o la CLI de Azure.

Los comandos de la CLI de Azure se pueden ejecutar en Azure Cloud Shell o en una estación de trabajo con la CLI de Azure instalada.

En primer lugar, use el comando az ad sp create-for-rbac para crear una nueva entidad de servicio para la aplicación. El comando también crea el registro de la aplicación para la aplicación al mismo tiempo.

az ad sp create-for-rbac --name {service-principal-name}

El resultado de este comando tendrá un aspecto similar al siguiente. Anote estos valores o mantenga abierta esta ventana, ya que necesitará estos valores en los pasos siguientes y no podrá volver a ver el valor de contraseña (secreto de cliente). Sin embargo, puede agregar una nueva contraseña más adelante sin invalidar la entidad de servicio o las contraseñas existentes si es necesario.

{
  "appId": "00000000-0000-0000-0000-000000000000",
  "displayName": "{service-principal-name}",
  "password": "abcdefghijklmnopqrstuvwxyz",
  "tenant": "33333333-3333-3333-3333-333333333333"
}

2- Creación de un grupo de seguridad de Microsoft Entra para el desarrollo local

Dado que normalmente hay varios desarrolladores que trabajan en una aplicación, se recomienda crear un grupo de seguridad de Microsoft Entra para encapsular los roles (permisos) que la aplicación necesita en el desarrollo local, en lugar de asignar los roles a objetos de entidad de servicio individuales. Esto ofrece las siguientes ventajas:

  • Todos los desarrolladores están seguros de tener asignados los mismos roles, ya que los roles se asignan en el nivel de grupo.
  • Si se necesita un nuevo rol para la aplicación, solo debe agregarse al grupo De Microsoft Entra para la aplicación.
  • Si un nuevo desarrollador se une al equipo, se crea una nueva entidad de servicio de aplicación para el desarrollador y esta se agrega al grupo, lo que garantiza que el desarrollador tiene los permisos adecuados para trabajar en la aplicación.

El comando az ad group create se usa para crear grupos de seguridad en Microsoft Entra ID. Los parámetros --display-name y --main-nickname son obligatorios. El nombre proporcionado al grupo debe basarse en el nombre de la aplicación. También resulta útil incluir una cadena como “local-dev” en el nombre del grupo para indicar el propósito del grupo.

az ad group create \
    --display-name MyDisplay \
    --mail-nickname MyDisplay  \
    --description "<group-description>"

Copie el valor de la id propiedad en la salida del comando. Este es el identificador de objeto del grupo. Lo necesita en pasos posteriores. También puede usar el comando az ad group show para recuperar esta propiedad.

Para agregar miembros al grupo, necesita el identificador de objeto de la entidad de servicio de la aplicación, que es diferente del identificador de aplicación. Use az ad sp list para enumerar las entidades de servicio disponibles. El comando de parámetro --filter acepta filtros de estilo de OData y se puede usar para filtrar la lista como se muestra. El parámetro --query limita las columnas solo a aquellas de interés.

az ad sp list \
    --filter "startswith(displayName, 'msdocs')" \
    --query "[].{objectId:id, displayName:displayName}" \
    --output table

El comando az ad group member add se puede usar para agregar miembros a grupos.

az ad group member add \
    --group <group-name> \
    --member-id <object-id>

Nota:

De forma predeterminada, la creación de grupos de seguridad de Microsoft Entra se limita a determinados roles con privilegios en un directorio. Si no puede crear un grupo, póngase en contacto con un administrador para el directorio. Si no puede agregar miembros a un grupo existente, póngase en contacto con el propietario del grupo o con un administrador de directorios. Para obtener más información, consulte Administración de grupos y pertenencia a grupos de Microsoft Entra.

3: Asignación de roles a la aplicación

A continuación, debe determinar qué roles (permisos) necesita la aplicación y en qué recursos para, a continuación, asignar dichos roles a la aplicación. En este ejemplo, los roles se asignan al grupo Microsoft Entra creado en el paso 2. Los roles se pueden asignar en un ámbito de recurso, grupo de recursos o suscripción. En este ejemplo se muestra cómo asignar roles en el ámbito del grupo de recursos, ya que la mayoría de las aplicaciones agrupan todos sus recursos de Azure en un único grupo de recursos.

A un usuario, grupo o entidad de servicio de aplicación se le asigna un rol en Azure mediante el comando az role assignment create . Puede especificar un grupo con su identificador de objeto. Puede especificar una entidad de servicio de aplicación con su appId.

az role assignment create --assignee {appId or objectId} \
    --scope /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName} \
    --role "{roleName}" 

Para obtener los nombres de rol que se pueden asignar, use el comando az role definition list .

az role definition list \
    --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
    --output table

Por ejemplo, para permitir que la entidad de servicio de la aplicación tenga el identificador de aplicación de acceso de lectura, escritura y eliminación a contenedores de blobs de Azure Storage y datos de todas las cuentas de almacenamiento en el grupo de recursos msdocs-python-sdk-auth-example de 00000000-0000-0000-0000-000000000000 la suscripción con el identificador 11111111-1111-1111-1111-111111111111, asignaría la entidad de servicio de la aplicación al rol Colaborador de datos de Storage Blob mediante el comando siguiente.

az role assignment create --assignee 00000000-0000-0000-0000-000000000000 \
    --scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/msdocs-python-sdk-auth-example \
    --role "Storage Blob Data Contributor"

Para obtener información sobre cómo asignar permisos en el nivel de recurso o suscripción mediante la CLI de Azure, consulte el artículo Asignación de roles de Azure mediante la CLI de Azure.

4- Establecimiento de variables de entorno de desarrollo local

El objeto DefaultAzureCredential buscará información sobre la entidad de servicio en un conjunto de variables de entorno en tiempo de ejecución. Dado que la mayoría de los desarrolladores trabajan en varias aplicaciones, se recomienda usar un paquete como python-dotenv para acceder al entorno desde un .env archivo almacenado en el directorio de la aplicación durante el desarrollo. Esto limita las variables de entorno que se usan para autenticar la aplicación en Azure de modo que esta aplicación solo las pueda usar.

El .env archivo nunca está protegido en el control de código fuente, ya que contiene la clave secreta de aplicación para Azure. El archivo .gitignore estándar para Python excluye automáticamente el .env archivo de la comprobación.

Para usar el paquete python-dotenv, instale primero el paquete en la aplicación.

pip install python-dotenv

A continuación, cree un .env archivo en el directorio raíz de la aplicación. Establezca los valores de las variables de entorno con los valores obtenidos del proceso de registro de aplicaciones de la siguiente manera:

  • AZURE_CLIENT_ID → Valor del id. de la aplicación.
  • AZURE_TENANT_ID → Valor del id. de inquilino.
  • AZURE_CLIENT_SECRET → Contraseña o credencial generada para la aplicación.
AZURE_CLIENT_ID=00000000-0000-0000-0000-000000000000
AZURE_TENANT_ID=11111111-1111-1111-1111-111111111111
AZURE_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz

Por último, en el código de inicio de la aplicación, use la python-dotenv biblioteca para leer las variables de entorno del .env archivo al iniciarse.

from dotenv import load_dotenv

if ( os.environ['ENVIRONMENT'] == 'development'):
    print("Loading environment variables from .env file")
    load_dotenv(".env")

5: Implementación de DefaultAzureCredential en la aplicación

Para autenticar objetos de cliente del SDK de Azure en Azure, la aplicación debe usar la DefaultAzureCredential clase del azure.identity paquete. En este escenario, DefaultAzureCredential detectará las variables AZURE_CLIENT_IDde entorno , AZURE_TENANT_IDy se establecen y AZURE_CLIENT_SECRET leen esas variables para obtener la información de la entidad de servicio de la aplicación con la que conectarse a Azure.

Empiece agregando el paquete azure.identity a la aplicación.

pip install azure-identity

A continuación, para cualquier código de Python que cree un objeto de cliente del SDK de Azure en la aplicación, querrá:

  1. Importe la DefaultAzureCredential clase desde el azure.identity módulo.
  2. Crear un objeto DefaultAzureCredential.
  3. Pase el DefaultAzureCredential objeto al constructor de objetos de cliente del SDK de Azure.

En el segmento de código siguiente se muestra un ejemplo de esto.

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

# Acquire a credential object
token_credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
        account_url="https://<my_account_name>.blob.core.windows.net",
        credential=token_credential)