Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Al compilar aplicaciones en la nube, los desarrolladores a menudo necesitan ejecutar y probar sus aplicaciones localmente. Incluso durante el desarrollo local, la aplicación debe autenticarse en los servicios de Azure con los que interactúa. En este artículo se explica cómo configurar identidades de entidad de servicio dedicadas específicamente para su uso durante el desarrollo local.
Las entidades de servicio de aplicaciones dedicadas para el desarrollo local admiten el principio de privilegios mínimos limitando el acceso solo a los recursos de Azure necesarios para la aplicación durante el desarrollo. El uso de una entidad de servicio de aplicación dedicada reduce el riesgo de acceso no deseado a otros recursos y ayuda a evitar errores relacionados con los permisos al realizar la transición a producción, donde los permisos más amplios podrían provocar problemas.
Al registrar aplicaciones para el desarrollo local en Azure, se recomienda:
- Crear registros de aplicaciones independientes para cada desarrollador: proporciona a cada desarrollador su propia entidad de servicio, evitando la necesidad de compartir credenciales y habilitando un control de acceso más granular.
- Crear registros de aplicaciones independientes para cada aplicación: esto garantiza que cada aplicación solo tenga los permisos que necesita, lo que reduce la posible superficie expuesta a ataques.
Para habilitar la autenticación durante el desarrollo local, establezca variables de entorno con las credenciales de la entidad de servicio de la aplicación. El SDK de Azure para Python detecta estas variables y las usa para autenticar las solicitudes en los servicios de Azure.
1: Registro de la aplicación en Azure
Los objetos principal de servicio de la aplicación son creados al registrar una aplicación en Azure. Este registro se puede realizar mediante Azure Portal o la CLI de Azure. El proceso de registro crea un registro de aplicación en Microsoft Entra ID (anteriormente Azure Active Directory) y genera un objeto de entidad de servicio para la aplicación. El objeto de principal de servicio se usa para autenticar la aplicación en los servicios de Azure.
El proceso de registro de aplicaciones también genera un secreto de cliente (contraseña) para la aplicación. Este secreto se usa para autenticar la aplicación en los servicios de Azure. El secreto de cliente nunca se almacena en el control de código fuente, sino en un .env
archivo del directorio de la aplicación. La .env
aplicación lee el archivo en tiempo de ejecución para establecer variables de entorno que el SDK de Azure para Python usa para autenticar la aplicación.
En los pasos siguientes se muestra cómo registrar una aplicación en Azure y crear una entidad de servicio para la aplicación. Los pasos se muestran para la CLI de Azure y Azure Portal.
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 aplicación para la aplicación al mismo tiempo.
SERVICE_PRINCIPAL_NAME=<service-principal-name>
az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME
La salida de este comando es similar a la siguiente. Anote estos valores o mantenga esta ventana abierta, ya que necesitará estos valores en los pasos siguientes y no podrá volver a ver el valor de la contraseña (secreto del cliente). Sin embargo, si es necesario, se puede agregar una nueva contraseña posteriormente sin invalidar la entidad de servicio ni las contraseñas existentes.
{
"appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"displayName": "<service-principal-name>",
"password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
"tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}
A continuación, debe obtener el appID
valor y almacenarlo en una variable. Este valor se usa para establecer variables de entorno en el entorno de desarrollo local para que el SDK de Azure para Python pueda autenticarse en Azure mediante la entidad de servicio.
APP_ID=$(az ad sp list \
--all \
--query "[?displayName=='$SERVICE_PRINCIPAL_NAME'].appId | [0]" \
--output tsv)
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 necesita la aplicación en el desarrollo local, en lugar de asignar los roles a objetos de entidad de servicio individuales. Esto ofrece las ventajas que se indican a continuación:
- 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 es necesario agregarlo al grupo 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.
GROUP_DISPLAY_NAME="<group-name>"
GROUP_MAIL_NICKNAME="<group-mail-nickname>"
GROUP_DESCRIPTION="<group-description>"
az ad group create \
--display-name $GROUP_DISPLAY_NAME \
--mail-nickname $GROUP_MAIL_NICKNAME \
--description $GROUP_DESCRIPTION
Para agregar miembros al grupo, necesitará el id. de objeto de la entidad de servicio de la aplicación, que es diferente al id. de la 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.
SP_OBJECT_ID=$(az ad sp list \
--filter "startswith(displayName,'$GROUP_DISPLAY_NAME')" \
--query "[0].id" \
--output tsv)
El comando az ad group member add se puede usar para agregar miembros a grupos.
az ad group member add \
--group $GROUP_DISPLAY_NAME \
--member-id $SP_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 del 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 de Microsoft Entra y pertenencia a grupos.
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 el á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 el rol en Azure con 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.
RESOURCE_GROUP_NAME=<resource-group-name>
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
ROLE_NAME=<role-name>
az role assignment create \
--assignee "$APP_ID" \
--scope "./subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME" \
--role "$ROLE_NAME"
! [! NOTA] Para evitar que Git Bash trate /subscriptions/... como ruta de acceso de archivo, anteponga ./ a la cadena para el
scope
parámetro y use comillas dobles alrededor de toda la cadena.
Para obtener los nombres de roles 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 aplicación con el appId de 00001111-aaaa-2222-bbbb-3333cccc4444
lea, escriba y elimine el acceso a los contenedores y datos de blobs de Azure Storage para todas las cuentas de almacenamiento del grupo de recursos msdocs-python-sdk-auth-example en la suscripción con ID aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e
, asignaría el rol de Colaborador de datos de blobs de almacenamiento a la entidad de servicio de la aplicación mediante el siguiente comando.
az role assignment create --assignee 00001111-aaaa-2222-bbbb-3333cccc4444 \
--scope "./subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/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 - Configuración de variables del 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 archivo .env
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 archivo .env
nunca se registra 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 archivo .env
de la protección.
Para usar el paquete python-dotenv, instale primero el paquete en la aplicación.
pip install python-dotenv
A continuación, cree un archivo .env
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=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6
Por último, en el código de inicio de la aplicación, use la biblioteca python-dotenv
para leer las variables de entorno del archivo .env
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 clase DefaultAzureCredential
del paquete azure.identity
. En este escenario, DefaultAzureCredential
detectará que las variables de entorno AZURE_CLIENT_ID
, AZURE_TENANT_ID
y AZURE_CLIENT_SECRET
están establecidas y las leerá 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 Python que cree un objeto cliente del SDK de Azure en su aplicación, querrá:
- Importar la clase
DefaultAzureCredential
desde el móduloazure.identity
. - Crear un objeto
DefaultAzureCredential
. - Pasar el objeto
DefaultAzureCredential
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)