我正在尝试使用具有服务主体身份验证的 Web API 从 Dataverse 中提取一些数据。当我在 Python 脚本中执行此操作时,一切正常,但在 ADF 中使用“复制数据”活动时遇到了一些问题。
这是我的工作代码:
BASE_URL = 'https://<org-url>.crm.dynamics.com'
credential = DefaultAzureCredential()
token = credential.get_token(BASE_URL + '/.default/)
headers = {
'Authorization': f'Bearer {token}',
'OData-Version': '4.0',
'OData-MaxVersion': '4.0',
'Accept': 'application/json',
}
url = F'{BASE_URL}/api/data/v9.2/<table>'
response = requests.get(url, headers=headers)
尝试使用复制数据活动在 ADF 中执行类似操作时,我收到以下错误之一:
https://<org-url>.crm.dynamics.com
作为基本 URL 放入 REST 链接服务时,我收到身份验证错误 401。https://<org-url>.crm.dynamics.com/.default
作为基本 URL 放入 REST 链接服务中时,我通过了身份验证,但得到了错误的响应,因为端点是 https://<org-url>.crm.dynamics.com/.default/api/data/v9.2/<table>
而不是 https://<org-url>.crm.dynamics.com/api/data/v9.2/<table>
我该如何解决这个问题?为什么需要这个
/.default
部分才能获得代币?
我创建了一个应用程序注册来调用 Dataverse API,并将其添加为 应用程序用户,并具有如下适当的角色:
要使用 服务主体 身份验证生成访问令牌,范围值必须以
/.default
结尾。
出于示例目的,我尝试通过运行下面的 python 代码来拉取 '/WhoAmI' API 响应,其中客户端 ID、客户端密码和租户 ID 添加为环境变量:
from azure.identity import DefaultAzureCredential
import requests
BASE_URL = 'https://orgxxxxxx.crm.dynamics.com'
credential = DefaultAzureCredential()
token = credential.get_token(BASE_URL + '/.default').token
headers = {
'Authorization': f'Bearer {token}',
'OData-Version': '4.0',
'OData-MaxVersion': '4.0',
'Accept': 'application/json',
}
url = f'{BASE_URL}/api/data/v9.2/WhoAmI'
response = requests.get(url, headers=headers)
print(response.json())
回复:
要使用 ADF 中的复制数据活动检索相同的数据并将响应发送到 Azure Blob 存储,您可以按照以下步骤操作:
首先,通过选择身份验证类型作为服务主体并使用以下配置来创建一个 REST 链接服务:
基本 URL:https://orgxxxxxx.crm.dynamics.com/api/data/v9.2/
身份验证类型:服务主体
服务主体 ID:appID
服务主体密钥:client_secret
租户:tenantID
Microsoft Entra ID 资源:https://orgxxxxxx.crm.dynamics.com
稍后,在 ADF 中创建一个 REST 数据集,并选择上面的链接服务,其中 “相对 URL” 为 WhoAmI(在您的情况下为
<table>
):
就我而言,我尝试将数据复制到Azure Blob Storage,需要为其创建以下链接服务:
稍后,创建一个JSON数据集,选择Azure Blob存储链接服务,文件路径如下:
现在,创建一个管道并向其添加复制数据活动,其中 source 作为 REST 数据集,sink 作为 JSON 数据集:
来源:
水槽:
回复:
为了确认这一点,我检查了 Azure Blob 存储中的文件,其中数据已成功检索,如下所示: