온-프레미스에서 호스트되는 Python 앱에서 Azure 리소스에 인증

Azure 외부(예: 온-프레미스 또는 타사 데이터 센터)에서 호스트되는 앱은 Azure 리소스에 액세스할 때 애플리케이션 서비스 주체를 사용하여 Azure에 인증해야 합니다. 애플리케이션 서비스 주체 개체는 Azure에서 앱 등록 프로세스를 사용하여 만들어집니다. 애플리케이션 서비스 주체가 만들어지면 앱에 대한 클라이언트 ID 및 클라이언트 암호가 생성됩니다. 그러면 클라이언트 ID, 클라이언트 암호 및 테넌트 ID가 환경 변수에 저장되므로 Python용 Azure SDK에서 런타임에 Azure에 앱을 인증하는 데 사용할 수 있습니다.

앱이 호스트되는 각 환경에 대해 다른 앱 등록을 만들어야 합니다. 이렇게 하면 각 서비스 주체에 대해 환경별 리소스 권한을 구성할 수 있으며, 한 환경에 배포된 앱이 다른 환경의 일부인 Azure 리소스와 통신하지 않도록 합니다.

1 - Azure에서 애플리케이션 등록

Azure Portal 또는 Azure CLI를 사용하여 Azure에서 앱을 등록할 수 있습니다.

az ad sp create-for-rbac --name <app-name>

명령의 출력은 다음과 유사합니다. 다음 단계에서 이러한 값이 필요하고 암호(클라이언트 암호) 값을 다시 볼 수 없으므로 이러한 값을 기록하거나 이 창을 열어 둡니다.

{
  "appId": "00000000-0000-0000-0000-000000000000",
  "displayName": "msdocs-python-sdk-auth-prod",
  "password": "abcdefghijklmnopqrstuvwxyz",
  "tenant": "33333333-3333-3333-3333-333333333333"
}

2 - 애플리케이션 서비스 주체에 역할 할당

다음으로, 어떤 리소스에 대해 앱에 필요한 역할(권한)을 결정하고 해당 역할을 앱에 할당해야 합니다. 역할은 리소스, 리소스 그룹 또는 구독 범위에서 역할을 할당할 수 있습니다. 이 예제에서는 대부분의 애플리케이션이 모든 Azure 리소스를 단일 리소스 그룹으로 그룹화하기 때문에 리소스 그룹 범위에서 서비스 주체에 대한 역할을 할당하는 방법을 보여 줍니다.

서비스 주체는 az role assignment create 명령을 사용하여 Azure에서 역할이 할당됩니다.

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

서비스 주체를 할당할 수 있는 역할 이름을 가져오려면 az role definition list 명령을 사용합니다.

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

예를 들어 id를 사용하여 구독11111111-1111-1111-1111-111111111111의 msdocs-python-sdk-auth-example 리소스 그룹에 있는 모든 스토리지 계정의 00000000-0000-0000-0000-000000000000 Azure Storage Blob 컨테이너 및 데이터에 대한 읽기, 쓰기 및 삭제 액세스 권한이 있는 서비스 주체를 허용하려면 다음 명령을 사용하여 애플리케이션 서비스 주체를 Storage Blob 데이터 기여자 역할에 할당합니다.

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"

Azure CLI를 사용하여 리소스 또는 구독 수준에서 권한을 할당하는 방법에 대한 자세한 내용은 Azure CLI를 사용하여 Azure 역할 할당 문서를 참조하세요.

3 - 애플리케이션에 대한 환경 변수 구성

Python 앱을 실행하는 프로세스에 대한 환경 변수 및 AZURE_CLIENT_SECRET 환경 변수를 설정AZURE_CLIENT_IDAZURE_TENANT_ID하여 런타임에 애플리케이션 서비스 주체 자격 증명을 앱에서 사용할 수 있도록 해야 합니다. 개체는 DefaultAzureCredential 이러한 환경 변수에서 서비스 주체 정보를 찾습니다.

Gunicorn을 사용하여 UNIX 서버 환경에서 Python 웹앱을 실행하는 경우 아래와 같이 파일의 EnvironmentFile 지시문을 사용하여 앱의 환경 변수를 gunicorn.server 지정할 수 있습니다.

[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

지시문에 EnvironmentFile 지정된 파일에는 아래와 같이 해당 값이 포함된 환경 변수 목록이 포함되어야 합니다.

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

4 - 애플리케이션에 DefaultAzureCredential 구현

Azure에 Azure SDK 클라이언트 개체를 인증하려면 애플리케이션에서 패키지의 클래스를 DefaultAzureCredentialazure.identity 사용해야 합니다.

먼저 애플리케이션에 azure.identity 패키지를 추가합니다.

pip install azure-identity

다음으로, 앱에서 Azure SDK 클라이언트 개체를 만드는 Python 코드의 경우 다음을 수행합니다.

  1. 모듈에서 DefaultAzureCredential 클래스를 azure.identity 가져옵니다.
  2. DefaultAzureCredential 개체를 만듭니다.
  3. 개체를 DefaultAzureCredential Azure SDK 클라이언트 개체 생성자에 전달합니다.

이 예제는 다음 코드 세그먼트에 나와 있습니다.

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)

위의 코드가 개체를 DefaultAzureCredential 인스턴스화할 때 환경 변수를 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET 읽고 애플리케이션 서비스 주체 정보를 사용하여 Azure에 연결합니다. DefaultAzureCredential