Compartilhar via


Autenticar recursos do Azure a partir de aplicativos Python hospedados localmente

Os aplicativos hospedados fora do Azure (por exemplo, no local ou em um data center de terceiros) devem usar uma entidade de serviço de aplicativo para autenticar no Azure ao acessar recursos do Azure. Os objetos da entidade de serviço de aplicativo são criados com um processo de registro de aplicativo no Azure. A criação de uma nova entidade de serviço de aplicativo gera uma ID de cliente e um segredo de cliente para seu aplicativo. Você armazena a ID do cliente, o segredo do cliente e sua ID de locatário em variáveis de ambiente a serem usadas pelo SDK do Azure para Python para autenticar seu aplicativo no Azure em runtime.

Um registro de aplicativo diferente deve ser criado para cada ambiente em que o aplicativo está hospedado. A criação de um registro de aplicativo diferente permite que permissões de recurso específicas do ambiente sejam configuradas para cada entidade de serviço e garante que um aplicativo implantado em um ambiente não fale com recursos do Azure que fazem parte de outro ambiente.

Registrar o aplicativo no Azure

Um aplicativo pode ser registrado no Azure usando o portal do Azure ou a CLI do Azure.

APP_NAME=<app-name>
az ad sp create-for-rbac --name $APP_NAME

A saída do comando é semelhante à seguinte. Anote esses valores ou mantenha essa janela aberta, já que você precisará desses valores nas próximas etapas e não poderá exibir o valor da senha (segredo do cliente) novamente.

{
  "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "displayName": "msdocs-python-sdk-auth-prod",
  "password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
  "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}

Em seguida, você precisa obter o appID valor e armazená-lo em uma variável. Esse valor é usado para definir variáveis de ambiente em seu ambiente de desenvolvimento local para que o SDK do Azure para Python possa se autenticar no Azure usando a entidade de serviço.

APP_ID=$(az ad sp create-for-rbac \
  --name $APP_NAME --query appId --output tsv)

Atribuir funções ao principal de serviço do aplicativo

Em seguida, você precisa determinar as funções (permissões) de que seu aplicativo precisa em quais recursos e atribuir essas funções ao seu aplicativo. As funções podem ser atribuídas a uma função em um recurso, grupo de recursos ou escopo de assinatura. Este exemplo mostra como atribuir funções para a entidade de serviço no escopo do grupo de recursos, uma vez que a maioria dos aplicativos agrupa todos os seus recursos do Azure em um único grupo de recursos.

Uma entidade de serviço recebe uma função no Azure usando o comando az role assignment create.

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"

![!OBSERVAÇÃO] Para impedir que o Git Bash trate /subscriptions/... como um caminho de arquivo, adicione no início ./ à string do parâmetro scope e use aspas duplas em toda a string.

Para obter os nomes de função aos quais uma entidade de serviço pode ser atribuída, use o comando az role definition list.

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

Por exemplo, para permitir que a entidade de serviço com o appId de 00001111-aaaa-2222-bbbb-3333cccc4444 leitura, gravação e exclusão acesse os contêineres do Azure Storage Blob e os dados em todas as contas de armazenamento no grupo de recursos msdocs-python-sdk-auth-example na assinatura com ID aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e, você deve atribuir a entidade de serviço do aplicativo à função de Colaborador de dados de blob de armazenamento usando o seguinte 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 obter informações sobre como atribuir permissões no nível de recurso ou assinatura usando a CLI do Azure, confira o artigo Atribuir funções do Azure usando a CLI do Azure.

Configurar variáveis de ambiente para aplicativo

Você deve definir as variáveis de ambiente AZURE_CLIENT_ID, AZURE_TENANT_ID e AZURE_CLIENT_SECRET para o processo que executa o aplicativo Python a fim de disponibilizar as credenciais principais do serviço de aplicativos para o aplicativo em tempo de execução. O objeto DefaultAzureCredential procura as informações principais do serviço nessas variáveis de ambiente.

Ao usar o Gunicorn para executar aplicativos Web Python em um ambiente de servidor UNIX, variáveis de ambiente para um aplicativo podem ser especificadas usando a EnvironmentFile diretiva no gunicorn.server. Veja o exemplo a seguir.

[Unit]
Description=gunicorn daemon
After=network.target  
  
[Service]  
User=www-user
Group=www-data
WorkingDirectory=/path/to/python-app
EnvironmentFile=/path/to/python-app/py-env/app-environment-variables
ExecStart=/path/to/python-app/py-env/gunicorn --config config.py wsgi:app
            
[Install]  
WantedBy=multi-user.target

O arquivo especificado na EnvironmentFile diretiva deve conter uma lista de variáveis de ambiente com seus valores da seguinte maneira.

AZURE_CLIENT_ID=<value>
AZURE_TENANT_ID=<value>
AZURE_CLIENT_SECRET=<value>

Implementar DefaultAzureCredential no aplicativo

Para autenticar objetos clientes do SDK do Azure no Azure, seu aplicativo deve usar a classe DefaultAzureCredential do pacote azure.identity.

Comece adicionando o pacote azure.identity ao seu aplicativo.

pip install azure-identity

Em seguida, para qualquer código Python que crie um objeto cliente do SDK do Azure em seu aplicativo, você deve:

  1. Importar a classe DefaultAzureCredential do módulo azure.identity.
  2. Crie um objeto DefaultAzureCredential.
  3. Passar o objeto DefaultAzureCredential para o construtor do objeto do cliente do SDK do Azure.

Um exemplo dessa abordagem é mostrado no segmento de código a seguir.

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)

Neste exemplo, quando o código cria uma instância do objeto DefaultAzureCredential, DefaultAzureCredential lê as variáveis de ambiente AZURE_TENANT_ID, AZURE_CLIENT_ID e AZURE_CLIENT_SECRET para obter as informações do principal de serviço do aplicativo para se conectar ao Azure.