如何在Azure Data Factory的Databricks Python脚本中通过MSI调用REST API
使用托管标识(MSI)从Databricks调用Azure Web App API的完整方案
完全可以用MSI替代硬编码凭据,而且有两种可行的方案,我会把细节和示例脚本都整理出来:
方案一:直接在Databricks脚本中使用MSI获取令牌(推荐)
这种方案不需要额外的ADF活动,直接在Python脚本中借助Azure的身份验证库自动获取MSI令牌,更简洁可靠。
前置准备
- 确保Web App启用Azure AD身份验证(Easy Auth):在Web App的"身份验证"设置里启用Azure AD作为身份提供者,这样API才能接受MSI颁发的令牌。
- 给MSI授予API访问权限:
- 如果用的是ADF的系统分配MSI:在Azure AD中找到你的Web App对应的企业应用(或应用注册),添加"API权限",选择你的Web App暴露的权限(比如
user_impersonation),然后完成管理员同意。 - 如果用的是Databricks集群的系统分配MSI:同样给这个集群的MSI授予上述Web App的API权限。
- 如果用的是ADF的系统分配MSI:在Azure AD中找到你的Web App对应的企业应用(或应用注册),添加"API权限",选择你的Web App暴露的权限(比如
- 安装必要的Python库:在Databricks集群上安装
azure-identity和requests:%pip install azure-identity requests
需要的关键信息
- Web App的应用ID(客户端ID):可以在Web App的"身份验证"设置里找到,或者Azure AD的应用注册中查看。这个值作为令牌请求的
resource或scope参数(取决于API的配置)。 - Web App的API URL:你的REST API的端点地址。
示例Python脚本
from azure.identity import DefaultAzureCredential import requests # 配置参数 API_URL = "https://your-web-app-name.azurewebsites.net/api/your-endpoint" # Web App的应用ID(客户端ID),作为令牌请求的资源 RESOURCE = "your-web-app-client-id" # 使用DefaultAzureCredential自动获取MSI令牌 # 这个类会自动检测环境中的MSI(ADF的MSI或Databricks集群的MSI) credential = DefaultAzureCredential() token = credential.get_token(f"{RESOURCE}/.default") # 构造请求头 headers = { "Authorization": f"Bearer {token.token}", "Content-Type": "application/json" } # 调用API response = requests.get(API_URL, headers=headers) response.raise_for_status() # 抛出HTTP错误如果请求失败 # 处理JSON响应 api_response = response.json() print("API响应:", api_response)
方案二:通过ADF Web活动获取令牌,再传递给Databricks活动
这种方案适合需要集中管理令牌获取逻辑的场景,步骤如下:
- 添加ADF Web活动:
- 设置活动类型为"Web",方法选择
GET。 - 在"身份验证"选项卡,选择"托管标识",资源填写Web App的应用ID(客户端ID)。
- 这个活动会向Azure AD请求令牌,响应中会包含
access_token字段。
- 设置活动类型为"Web",方法选择
- 传递令牌给Databricks活动:
- 在Databricks活动的"参数"里添加一个参数,比如
api_token,值设置为@activity('Web活动名称').output.access_token。
- 在Databricks活动的"参数"里添加一个参数,比如
- Databricks脚本中使用令牌:
从参数中获取令牌,直接作为Authorization头调用API:import requests # 从ADF传递的参数中获取令牌 api_token = dbutils.widgets.get("api_token") API_URL = "https://your-web-app-name.azurewebsites.net/api/your-endpoint" headers = { "Authorization": f"Bearer {api_token}", "Content-Type": "application/json" } response = requests.get(API_URL, headers=headers) response.raise_for_status() api_response = response.json() print("API响应:", api_response)
常见问题说明
- 如果你的Web App用的是应用ID URI而不是客户端ID作为资源标识,只需要把脚本中的
RESOURCE替换成对应的URI即可。 DefaultAzureCredential会自动适配多种环境,包括ADF托管的Databricks活动、Databricks集群自身的MSI,不需要额外配置。- 确保MSI的权限已经被正确授予,否则会出现"权限不足"的错误。
内容的提问来源于stack exchange,提问作者pelos
相关产品推荐
相关产品推荐

