Compartir vía


Cadenas de credenciales en la biblioteca cliente de identidades de Azure para Python

La biblioteca cliente de identidades de Azure proporciona credenciales, clases públicas que implementan el protocolo TokenCredential de la biblioteca de Azure Core. Una credencial representa un flujo de autenticación distinto para adquirir un token de acceso de Microsoft Entra ID. Estas credenciales se pueden encadenar para formar una secuencia ordenada de mecanismos de autenticación que se van a intentar.

Funcionamiento de una credencial encadenada

En tiempo de ejecución, una cadena de credenciales intenta autenticarse mediante la primera credencial de la secuencia. Si esa credencial no puede adquirir un token de acceso, se intenta utilizar la siguiente credencial de la secuencia, y así sucesivamente hasta que se obtenga correctamente un token de acceso. En el siguiente diagrama de secuencia se ilustra este comportamiento:

Diagrama que muestra la secuencia de la cadena de credenciales.

¿Por qué usar cadenas de credenciales?

Una credencial encadenada puede ofrecer las siguientes ventajas:

  • Reconocimiento del entorno: selecciona automáticamente la credencial más adecuada en función del entorno en el que se ejecuta la aplicación. Sin ella, tendría que escribir código como este:

    # Set up credential based on environment (Azure or local development)
    if os.getenv("WEBSITE_HOSTNAME"):
        credential = ManagedIdentityCredential(client_id=user_assigned_client_id)
    else:
        credential = AzureCliCredential()
    
  • Transiciones fluidas: la aplicación puede pasar del desarrollo local al entorno de ensayo o producción sin cambiar el código de autenticación.

  • Resistencia mejorada: incluye un mecanismo de reserva que pasa a la siguiente credencial cuando la anterior no puede adquirir un token de acceso.

Cómo elegir una credencial encadenada

Hay dos filosofías dispares para encadenar credenciales:

Información general sobre DefaultAzureCredential

DefaultAzureCredential es una cadena preconfigurada de credenciales fundamentada. Está diseñada para admitir muchos entornos, junto con los flujos de autenticación y las herramientas de desarrollo más comunes. En forma gráfica, la cadena subyacente tiene este aspecto:

Diagrama que muestra el flujo de autenticación DefaultAzureCredential.

Orden en el que DefaultAzureCredential intenta las credenciales.

compra Credential: Descripción ¿Habilitado de forma predeterminada?
1 Entorno Lee una colección de variables de entorno para determinar si una entidad de servicio de aplicación (usuario de aplicación) está configurada para la aplicación. Si es así, DefaultAzureCredential usa estos valores para autenticar la aplicación en Azure. Este método se usa con más frecuencia en entornos de servidor, pero también se puede usar al desarrollar localmente.
2 Identidad de carga de trabajo Si la aplicación se implementa en un host de Azure con la identidad de carga de trabajo habilitada, autentica esa cuenta.
3 Identidad administrada Si la aplicación se implementa en un host de Azure con la identidad administrada habilitada, se autentica la aplicación en Azure usando esa identidad administrada.
4 Caché de tokens compartidos Solo en Windows, si el desarrollador se autentica en Azure iniciando sesión en Visual Studio, autentique la aplicación en Azure con esa misma cuenta.
5 CLI de Azure Si el desarrollador se autenticó en Azure mediante el comando az login de la CLI de Azure, se autentica la aplicación en Azure con esa misma cuenta.
6 Azure PowerShell Si el desarrollador se autenticó en Azure mediante el cmdlet Connect-AzAccount de Azure PowerShell, se autentica la aplicación en Azure con esa misma cuenta.
7 CLI de desarrollo de Azure Si el desarrollador se autenticó en Azure mediante el comando azd auth login de la CLI para desarrolladores de Azure, se autentica con esa cuenta.
8 Navegador interactivo Si está habilitado, autenticará de forma interactiva al desarrollador mediante el explorador predeterminado del sistema actual. No

En su forma más sencilla, puede usar la versión sin parámetros de DefaultAzureCredential de la siguiente manera:

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

# Acquire a credential object
credential = DefaultAzureCredential()

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

Personalización de DefaultAzureCredential

Para quitar una credencial de DefaultAzureCredential, use el parámetro de palabra clave con el prefijo exclude correspondiente. Por ejemplo:

credential = DefaultAzureCredential(
    exclude_environment_credential=True, 
    exclude_workload_identity_credential=True,
    managed_identity_client_id=user_assigned_client_id
)

En el ejemplo de código anterior, EnvironmentCredential y WorkloadIdentityCredential se quitan de la cadena de credenciales. Como resultado, la primera credencial que se va a intentar es ManagedIdentityCredential. La cadena modificada tiene este aspecto:

Diagrama que muestra el flujo de autenticación de una instancia de DefaultAzureCredential después de usar parámetros de palabra clave con prefijo de exclusión en el constructor para quitar credenciales de entorno y credenciales de identidad de carga de trabajo.

Nota:

InteractiveBrowserCredential se excluye de forma predeterminada y, por tanto, no se muestra en el diagrama anterior. Para incluir InteractiveBrowserCredential, establezca el parámetro de palabra clave exclude_interactive_browser_credential en False al llamar al constructor de DefaultAzureCredential.

A medida que se establecen más parámetros de palabra clave con el prefijo exclude en True (se configuran exclusiones de credenciales), las ventajas de usar DefaultAzureCredential disminuyen. En tales casos, ChainedTokenCredential es una mejor opción y requiere menos código. Para ilustrarlo, estos dos ejemplos de código se comportan de la misma manera:

credential = DefaultAzureCredential(
    exclude_environment_credential=True,
    exclude_workload_identity_credential=True,
    exclude_shared_token_cache_credential=True,
    exclude_azure_powershell_credential=True,
    exclude_azure_developer_cli_credential=True,
    managed_identity_client_id=user_assigned_client_id
)

Información general sobre ChainedTokenCredential

ChainedTokenCredential es una cadena vacía a la que agrega credenciales para satisfacer las necesidades de la aplicación. Por ejemplo:

credential = ChainedTokenCredential(
    ManagedIdentityCredential(client_id=user_assigned_client_id),
    AzureCliCredential()
)

El ejemplo de código anterior crea una cadena de credenciales adaptada formada por dos credenciales. La variante de identidad administrada asignada por el usuario de ManagedIdentityCredential se intenta primero, seguida de AzureCliCredential, si es necesario. En forma gráfica, la cadena tiene este aspecto:

Diagrama que muestra el flujo de autenticación de una instancia de ChainedTokenCredential compuesta por credenciales de identidad administrada y credenciales de la CLI de Azure.

Sugerencia

Para mejorar el rendimiento, optimice el orden de las credenciales en ChainedTokenCredential para el entorno de producción. Las credenciales diseñadas para su uso en el entorno de desarrollo local deben agregarse en último lugar.

Guía de uso para DefaultAzureCredential

DefaultAzureCredential es, sin duda, la manera más fácil de empezar a trabajar con la biblioteca cliente de identidades de Azure, pero esa comodidad conlleva ventajas y desventajas. Una vez que implemente la aplicación en Azure, debe comprender los requisitos de autenticación de la aplicación. Por esa razón, considere encarecidamente la posibilidad de pasar de DefaultAzureCredential a una de las siguientes soluciones:

  • Una implementación de credencial específica, como ManagedIdentityCredential.
  • Una implementación de ChainedTokenCredential reducida optimizada para el entorno Azure en el que se ejecuta la aplicación.

Aquí se detallan los motivos:

  • Desafíos de depuración: cuando se produce un error en la autenticación, puede resultar difícil depurar e identificar las credenciales incorrectas. Debe habilitar el registro para ver la progresión de una credencial a la siguiente y el estado de éxito o error de cada una. Para obtener más información, consulte Depuración de una credencial encadenada.
  • Sobrecarga de rendimiento: el proceso de probar secuencialmente varias credenciales puede suponer una sobrecarga de rendimiento. Por ejemplo, cuando se ejecuta en una máquina de desarrollo local, la identidad administrada no está disponible. Por lo tanto, ManagedIdentityCredential siempre falla en el entorno de desarrollo local, a menos que se deshabilite explícitamente a través de su propiedad con prefijo exclude correspondiente.
  • Comportamiento imprevisible: DefaultAzureCredential comprueba la presencia de determinadas variables de entorno. Es posible que alguien pueda agregar o modificar estas variables de entorno en el nivel de sistema en el equipo host. Esos cambios se aplican globalmente y, por tanto, modifican el comportamiento de DefaultAzureCredential en tiempo de ejecución en cualquier aplicación que se ejecute en esa máquina.

Depuración de una credencial encadenada

Para diagnosticar un problema inesperado o comprender lo que hace una credencial encadenada, habilite el registro en la aplicación. Opcionalmente, filtre los registros solo a esos eventos emitidos desde la biblioteca cliente de identidades de Azure. Por ejemplo:

import logging
from azure.identity import DefaultAzureCredential

# Set the logging level for the Azure Identity library
logger = logging.getLogger("azure.identity")
logger.setLevel(logging.DEBUG)

# Direct logging output to stdout. Without adding a handler,
# no logging output is visible.
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

# Optional: Output logging levels to the console.
print(
    f"Logger enabled for ERROR={logger.isEnabledFor(logging.ERROR)}, "
    f"WARNING={logger.isEnabledFor(logging.WARNING)}, "
    f"INFO={logger.isEnabledFor(logging.INFO)}, "
    f"DEBUG={logger.isEnabledFor(logging.DEBUG)}"
)

Para fines ilustrativos, supongamos que se usa la forma sin parámetros de DefaultAzureCredential para autenticar una solicitud en una cuenta ed Blob Storage. La aplicación se ejecuta en el entorno de desarrollo local y el desarrollador se autentica en Azure mediante la CLI de Azure. Supongamos también que el nivel de registro está establecido en logging.DEBUG. Cuando se ejecuta la aplicación, aparecen las siguientes entradas pertinentes en la salida:

Logger enabled for ERROR=True, WARNING=True, INFO=True, DEBUG=True
No environment configuration found.
ManagedIdentityCredential will use IMDS
EnvironmentCredential.get_token failed: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
Visit https://aka.ms/azsdk/python/identity/environmentcredential/troubleshoot to troubleshoot this issue.
ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.     
SharedTokenCacheCredential.get_token failed: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
AzureCliCredential.get_token succeeded
[Authenticated account] Client ID: 00001111-aaaa-2222-bbbb-3333cccc4444. Tenant ID: aaaabbbb-0000-cccc-1111-dddd2222eeee. User Principal Name: unavailableUpn. Object ID (user): aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb
DefaultAzureCredential acquired a token from AzureCliCredential

En la salida anterior, puede ver lo siguiente:

  • EnvironmentCredential, ManagedIdentityCredential y SharedTokenCacheCredential no pudieron adquirir un token de acceso de Microsoft Entra, en ese orden.
  • La llamada a AzureCliCredential.get_token se realiza correctamente y la salida también indica que DefaultAzureCredential adquirió un token de AzureCliCredential. Dado que AzureCliCredential se realizó correctamente, no se intentaron más credenciales.

Nota:

En el ejemplo anterior, el nivel de registro está establecido en logging.DEBUG. Tenga cuidado al usar este nivel de registro, ya que puede generar información confidencial. Por ejemplo, en este caso, el identificador de cliente, el identificador de inquilino y el identificador de objeto de la entidad de usuario del desarrollador en Azure. Toda la información de seguimiento se ha quitado de la salida para mayor claridad.