迁移Python ADAL自定义指标Azure函数以支持托管身份

问题描述

我有一个使用预览选项的Python函数,该预览选项使用REST API https://docs.microsoft.com/en-us/azure/azure-monitor/platform/metrics-store-custom-rest-api将自定义指标发送到Azure,以前这是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)

显然,这依赖于我创建具有相关权限的服务主体。我正在尝试找出如何使用C#库具有的自动托管身份授权。

我知道应该用MSAL代替ADAL,但是我不知道如何/是否自动处理托管身份,所以我尝试了天蓝色身份:

from azure.identity import DefaultAzureCredential

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

这给我一个令牌,但是因为它需要一个作用域而不是一个资源,这意味着向资源URL添加.default,当我将承载令牌发送到监视端点时,它抱怨资源不匹配并且必须是完全是“ https://monitoring.azure.com/”

这是当前不可能吗,还是我缺少带有天蓝色身份或MSAL Python模块的东西?

解决方法

根据我的研究,当要求使用Azure AD令牌发出自定义指标时,请确保请求该令牌的受众是https://monitoring.azure.com/。有关更多详细信息,请参阅here。因此,我们应该将范围更新为https://monitoring.azure.com//.default enter image description here

例如

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)

enter image description here enter image description here

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...