Compartilhar via


Cadeias de credenciais na biblioteca de cliente da identidade do Azure para Python

A biblioteca de cliente da Identidade do Azure fornece credenciais, classes públicas que implementam o protocolo TokenCredential da biblioteca do Azure Core. Uma credencial representa um fluxo de autenticação distinto para adquirir um token de acesso do Microsoft Entra ID. Essas credenciais podem ser encadeadas para formar uma sequência ordenada de mecanismos de autenticação a serem tentados.

Como funciona uma credencial encadeada

No tempo de execução, uma cadeia de credenciais tenta autenticar usando a primeira credencial da sequência. Se essa credencial não conseguir adquirir um token de acesso, a próxima credencial na sequência será tentada e assim por diante, até que um token de acesso seja obtido com êxito. O diagrama de sequência a seguir ilustra esse comportamento:

Diagrama que mostra a sequência da cadeia de credenciais.

Por que usar cadeias de credenciais

Uma credencial encadeada pode oferecer os seguintes benefícios:

  • Reconhecimento de ambiente: seleciona automaticamente a credencial mais apropriada com base no ambiente em que o aplicativo está sendo executado. Sem ele, você teria que escrever um 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()
    
  • Transições perfeitas: seu aplicativo pode passar do desenvolvimento local para o ambiente de preparo ou produção sem alterar o código de autenticação.

  • Resiliência aprimorada: inclui um mecanismo de fallback que se move para a próxima credencial quando a anterior não consegue adquirir um token de acesso.

Como escolher uma credencial encadeada

Existem duas filosofias diferentes para o encadeamento de credenciais:

Visão geral do DefaultAzureCredential

DefaultAzureCredential é uma cadeia de credenciais opinativa e pré-configurada. Ele foi projetado para dar suporte a muitos ambientes, juntamente com os fluxos de autenticação e ferramentas de desenvolvedor mais comuns. Em forma gráfica, a cadeia subjacente se parece com isso:

Diagrama que mostra o fluxo de autenticação DefaultAzureCredential.

A ordem na qual as credenciais de tentativas DefaultAzureCredential seguem.

Pedido Credencial Descrição Habilitado por padrão?
1 Ambiente Lê uma coleção de variáveis de ambiente para determinar se uma entidade de serviço de aplicativo (usuário do aplicativo) está configurada para o aplicativo. Nesse caso, DefaultAzureCredential usa esses valores para autenticar o aplicativo no Azure. Esse método geralmente é usado em ambientes de servidor, mas também pode ser usado ao desenvolver localmente. Sim
2 Identidade da Carga de Trabalho Se o aplicativo for implantado em um host do Azure com a Identidade de Carga de Trabalho habilitada, autentique essa conta. Sim
3 Identidade Gerenciada Se o aplicativo for implantado em um host do Azure com a Identidade Gerenciada habilitada, autentique o aplicativo no Azure usando essa Identidade Gerenciada. Sim
4 Cache de token compartilhado Somente no Windows, se o desenvolvedor tiver se autenticado no Azure fazendo logon no Visual Studio, autentique o aplicativo no Azure usando essa mesma conta. Sim
5 CLI do Azure Se o desenvolvedor tiver se autenticado no Azure usando o comando da CLI do Azure az login, autentique o aplicativo no Azure usando essa mesma conta. Sim
6 PowerShell do Azure Se o desenvolvedor tiver sido autenticado no Azure usando o cmdlet do Azure PowerShell Connect-AzAccount, autentique o aplicativo no Azure usando essa mesma conta. Sim
7 CLI do Desenvolvedor do Azure Se o desenvolvedor tiver se autenticado no Azure usando o comando da CLI do Desenvolvedor do Azure azd auth login, autentique-se com essa conta. Sim
8 Navegador interativo Se habilitado, autentique interativamente o desenvolvedor por meio do navegador padrão do sistema atual. Não

Em sua forma mais simples, você pode usar a versão sem parâmetros de DefaultAzureCredential da seguinte maneira:

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
)

Como personalizar DefaultAzureCredential

Para remover uma credencial do DefaultAzureCredential, use o parâmetro de palavra-chave exclude-prefixed correspondente. Por exemplo:

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

No exemplo de código anterior, EnvironmentCredential e WorkloadIdentityCredential são removidos da cadeia de credenciais. Como resultado, a primeira credencial a ser tentada é ManagedIdentityCredential. A cadeia modificada tem esta aparência:

Diagrama que mostra o fluxo de autenticação para uma instância DefaultAzureCredential depois de usar parâmetros de palavra-chave prefixados de exclusão no construtor para remover a credencial de ambiente e a credencial de identidade de carga de trabalho.

Observação

InteractiveBrowserCredential é excluído por padrão e, portanto, não é mostrado no diagrama anterior. Para incluir InteractiveBrowserCredential, defina o exclude_interactive_browser_credential parâmetro de palavra-chave como False quando você chamar o construtor DefaultAzureCredential.

À medida que mais parâmetros de palavras-chave exclude-prefixed são definidos como True (as exclusões de credenciais estão configuradas), as vantagens de utilizar DefaultAzureCredential diminuem. Nesses casos, ChainedTokenCredential é uma escolha melhor e requer menos código. Para ilustrar, esses dois exemplos de código se comportam da mesma maneira:

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
)

Visão geral do ChainedTokenCredential

ChainedTokenCredential é uma cadeia vazia à qual você adiciona credenciais para atender às necessidades do seu aplicativo. Por exemplo:

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

O exemplo de código anterior cria uma cadeia de credenciais personalizada composta por duas credenciais. A variante de identidade gerenciada atribuída pelo usuário ManagedIdentityCredential é tentada primeiro, seguida por AzureCliCredential, se necessário. Em forma gráfica, a cadeia se parece com isso:

Diagrama que mostra o fluxo de autenticação para uma instância ChainedTokenCredential composta por credencial de identidade gerenciada e credencial da CLI do Azure.

Dica

Para melhorar o desempenho, otimize a ordenação de credenciais em ChainedTokenCredential para seu ambiente de produção. As credenciais destinadas ao uso no ambiente de desenvolvimento local devem ser adicionadas por último.

Diretrizes de uso para DefaultAzureCredential

DefaultAzureCredential é, sem dúvida, a maneira mais fácil de começar a usar a biblioteca de cliente da Identidade do Azure, mas com essa conveniência vêm compensações. Depois de implantar seu aplicativo no Azure, você deve entender os requisitos de autenticação do aplicativo. Por esse motivo, considere fortemente mudar de DefaultAzureCredential para uma das seguintes soluções:

  • Uma implementação de credencial específica, como ManagedIdentityCredential.
  • Uma implementação ChainedTokenCredential simplificada e otimizada para o ambiente do Azure no qual seu aplicativo é executado.

Eis o motivo:

  • Desafios de depuração: quando a autenticação falha, pode ser um desafio depurar e identificar a credencial ofensiva. Você deve habilitar o registro em log para ver a progressão de uma credencial para a próxima e o status de sucesso/falha de cada uma. Para obter mais informações, consulte Depurar uma credencial encadeada.
  • Sobrecarga de desempenho: o processo de tentar sequencialmente várias credenciais pode introduzir sobrecarga de desempenho. Por exemplo, ao executar em um computador de desenvolvimento local, a identidade gerenciada não está disponível. Consequentemente, ManagedIdentityCredential sempre falha no ambiente de desenvolvimento local, a menos que explicitamente desabilitado por meio de sua propriedade prefixada exclude correspondente.
  • Comportamento imprevisível: DefaultAzureCredential verifica a presença de determinadas variáveis de ambiente. É possível que alguém possa adicionar ou modificar essas variáveis de ambiente no nível do sistema na máquina host. Essas alterações se aplicam globalmente e, portanto, alteram o comportamento de DefaultAzureCredential em tempo de execução em qualquer aplicativo em execução nesse computador.

Depurar uma credencial encadeada

Para diagnosticar um problema inesperado ou entender o que uma credencial encadeada está fazendo, habilite o registro em log em seu aplicativo. Opcionalmente, filtre os logs apenas para os eventos emitidos da biblioteca de cliente da Identidade do Azure. Por exemplo:

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 fins de ilustração, suponha que a forma sem parâmetros de DefaultAzureCredential é utilizado para autenticar um pedido a uma conta de armazenamento de Blob. O aplicativo é executado no ambiente de desenvolvimento local e o desenvolvedor é autenticado no Azure usando a CLI do Azure. Suponha também que o nível de registro esteja definido como logging.DEBUG. Quando o aplicativo é executado, as seguintes entradas pertinentes aparecem na saída:

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

Na saída anterior, observe que:

  • EnvironmentCredential, ManagedIdentityCredential e SharedTokenCacheCredential cada um falhou ao adquirir um token de acesso do Microsoft Entra, nessa ordem.
  • A chamada AzureCliCredential.get_token é bem-sucedida e a saída também indica que DefaultAzureCredential adquiriu um token do AzureCliCredential. Desde que AzureCliCredential foi bem-sucedido, não foram tentadas outras credenciais para além desta.

Observação

No exemplo anterior, o nível de registo é definido para logging.DEBUG. Tenha cuidado ao usar esse nível de registro, pois ele pode gerar informações confidenciais. Por exemplo, nesse caso, a ID do cliente, a ID do locatário e a ID do objeto da entidade de usuário do desenvolvedor no Azure. Todas as informações de rastreamento foram removidas da saída para maior clareza.