Перенос пользовательских метрик Python ADAL в функцию Azure для поддержки управляемой идентификации

У меня есть функция Python, использующая опцию предварительного просмотра для отправки пользовательских метрик в Azure с помощью REST API https://docs.microsoft.com/en-us/azure/azure-monitor/platform/metrics-store-custom-rest-api, ранее это была функция C #, в которой авторизация и получение токена-носителя обрабатывались автоматически:

var azureServiceTokenProvider = new AzureServiceTokenProvider();
string bearerToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://monitoring.azure.com/").ConfigureAwait(false);

Это работало в VS Code с использованием вошедшего в систему пользователя и в Azure, когда функции была назначена управляемая идентификация.

Мне нужно было преобразовать это в Python, но пока лучшее (работающее), которое я смог придумать, это:

import logging, requests, os, adal
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    regional_monitoring_url = "https://eastus.monitoring.azure.com"
    monitored_resource_id = os.environ['RESOURCE_ID']
    full_endpoint = f"{regional_monitoring_url}{monitored_resource_id}/metrics"

    tenant_id = os.environ['AZURE_TENANT_ID']
    context = adal.AuthenticationContext(f'https://login.microsoftonline.com/{tenant_id}')
    token = context.acquire_token_with_client_credentials("https://monitoring.azure.com/", os.environ['AZURE_CLIENT_ID'], os.environ['AZURE_CLIENT_SECRET']    )
    bearer_token = token['accessToken']

    json = req.get_json()
    headers = {"Authorization": 'Bearer ' + bearer_token}
    result = requests.post(url = full_endpoint, headers = headers, json = json)

    return func.HttpResponse(f"Done - {result.status_code} {result.text}", status_code=200)

Очевидно, это зависит от того, что я создаю субъекта-службы с соответствующими разрешениями. Я пытаюсь понять, как использовать автоматическую авторизацию Managed Identity, которая есть в библиотеках C #.

Я знаю, что ADAL следует заменить на MSAL, но я не могу понять, как / если это автоматически обрабатывает управляемые удостоверения, поэтому я попробовал azure-identity:

from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
token = credential.get_token("https://monitoring.azure.com/.default")
bearer_token = token.token

Это дает мне токен, но поскольку для этого требуется область, а не ресурс, что означает добавление .default к URL-адресу ресурса, когда я отправляю токен-носитель в конечную точку мониторинга, он жалуется, что ресурс не совпадает и должен быть точно https: //monitoring.azure.com/

Это просто в настоящее время невозможно, или мне что-то не хватает либо с azure-identity, либо с модулями MSAL Python?


person Simon    schedule 11.09.2020    source источник


Ответы (1)


Согласно моему исследованию, когда мы запрашивали токен Azure AD для выдачи настраиваемых показателей, убедитесь, что аудитория, для которой запрашивается токен, является https://monitoring.azure.com/. Дополнительные сведения см. здесь. Поэтому мы должны обновить область как https://monitoring.azure.com//.default  введите описание изображения здесь

Например

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    credential = DefaultAzureCredential()
    token = credential.get_token("https://monitoring.azure.com//.default")
    bearer_token = token.token
    #full_endpoint=""
    json = req.get_json()
    headers = {"Authorization": 'Bearer ' + bearer_token}
    #result = requests.post(url = full_endpoint, headers = headers, json = json)
    return func.HttpResponse(f"Done - {bearer_token}", status_code=200)

введите описание изображения здесь  введите описание изображения здесь

person Jim Xu    schedule 13.09.2020
comment
Ух, вы говорите мне, что это было что-то столь же глупое, как двойное // в ресурсе :-( попробую в ближайшее время, несколько раздраженный, я не подумал попробовать это. Когда он сказал добавить /.default, я просто предположил двойное // будет преобразовано в одиночное / - person Simon; 13.09.2020