我在尝试使用 PowerQuery 将 API 数据导入 Excel 电子表格时也遇到了这个错误,并且很难通过它,主要是因为关于这一切的文档有点少。
问题 - 如何将数据从 Azure 中的 API 导入 Excel 电子表格?
我有一个在 Azure 中运行的 ASP.NET API,并在我自己的域中以 URL 公开,例如https://api.myapp.net(而不是内置的 azure URL)。此 API 通过 OWIN 中间件连接到 Azure AD:UseWindowsAzureActiveDirectoryBearerAuthentication,即 Azure 中的应用服务已关闭 AAD 身份验证。该应用程序在 AAD 中注册为多租户,在与托管应用服务资源的不同租户中。
问题 1 - 凭据
所以首先在 Excel 中执行 Data > From Web > https://api.myapp.net/Products 并选择“Organisational Account”并单击“Sign-in”,出现此错误:
对此有两种不同的修复方法:
1。在所有 401 上返回 WWW-Authenticate 响应标头
如果你已经在你的 API 中使用 owin 中间件在代码中启用了 AAD,那么你需要确保服务在给客户端的 401 响应中返回正确的WWW-Authenticate 头,具体我们必须指定 AAD 登录端点作为授权 uri,例如:
WWW-Authenticate: Bearer realm="",
authorization_uri="https://login.microsoftonline.com/<<tenant id of your users>>"
见:this TechNet question which suggested this solution
2。在 Azure 门户中为 API 应用服务开启 AAD 身份验证
- 或者在托管应用服务本身的租户的 Azure 门户中
- 转到应用服务并找到 API 应用服务
- 在身份验证/授权中打开应用服务身份验证
- 对于“未经身份验证时采取的操作”选择“使用 Azure Active Directory 登录”
- 在“身份验证提供程序”下单击“Azure Active Directory”并选择“高级”设置
- 在“客户端 ID”下输入 API 应用注册的应用 ID
- 在“Issuer Url”下,输入 API 用户源自的租户的登录端点
- 在“允许的令牌受众”下,确保您已添加 API 的实际 URL,例如https://api.myapp.net
- 保存更改
基本上这个配置被描述为here
问题 2 - 应用注册
现在返回 Excel,当您在查询中单击登录时,将打开一个弹出窗口并将您带到您配置的租户的 Microsoft 登录页面。当您输入凭据并登录时,您可能会收到此错误(问题中的那个):
要解决此问题,您需要确保应用程序已正确注册到 AAD。
这里是...
- 在注册应用程序的租户的 Azure 门户中
- 转到 Azure Active Directory > 应用注册并找到 API 服务的注册
- 编辑 Manifest 并确保在 identifierUris 列表中配置了实际部署的 API URL,例如https://api.myapp.net(会有一个 Azure 内置 URL 已经配置好了)
{
"identifierUris": [
"https://api.myapp.net",
"https://<mytenant>.onmicrosoft.com/<myappregname>"
]
}
{
"oauth2Permissions": [
{
"adminConsentDescription": "Allow the application to access myapp on behalf of the signed-in user.",
"adminConsentDisplayName": "Access myapp",
"id": "xxxxx-xxx-xxx-xxx-xxxxxxx",
"isEnabled": true,
"lang": null,
"origin": "Application",
"type": "User",
"userConsentDescription": "Allow the application to access my on your behalf.",
"userConsentDisplayName": "Access my app",
"value": "user_impersonation"
}
]
}
问题 3 - 允许的令牌受众
现在回到 Excel 中,您应该能够通过登录,但是当单击“连接”时,您可能会收到以下错误:
现在查看 fiddler,您将看到 AAD 登录有效并返回一个令牌,但是当它发送到 API 时,您会得到一个 401。
仅当您通过代码而不是通过 Azure 门户启用 AAD 时才会出现此问题(请参阅上面的问题 1!)。要修复它,您需要确保传递给 owin 中间件的 TokenValidationParameters class 已将 ValidAudience 设置为已部署 API 的实际 URL。
运行查询
完成所有设置后,现在一切都应该可以正常工作了,回到 Excel ...
- 单击登录将打开一个弹出窗口,将您带到您配置的租户的 Microsoft 登录页面,使用您的凭据登录
- 点击连接
- PowerQuery 编辑器随后将打开并显示从 API 检索到的数据
- 单击主页 > 高级编辑器,您将能够查看原始查询 - 这是在 M-query syntax PowerQuery 使用的查询语言中,在我的情况下,数据是一个平面数组,所以这就足够了:
let
Source = Json.Document(Web.Contents("https://api.myapp.net/Products")),
#"Converted to Table" = Table.FromRecords(Source)
in
#"Converted to Table"
这是如何工作的
如果您关心(并且仍在阅读此内容!),它的工作方式似乎是:
- PowerQuery 请求在“Microsoft PowerQuery For Excel”内置应用程序下访问您的 API(客户端 ID a672d62c-fc7b-4e81-a576-e60dc46e951d)
- 当您登录时,AAD 会将您 API 上的动态范围
user_impersonation(由资源 URL https://api.myapp.net 标识)授予“Microsoft PowerQuery For Excel”应用
- 您可以在门户中通过转到企业应用程序、检查 Microsoft 应用程序并搜索 Microsoft PowerQuery For Excel 来查看此内容
很抱歉,这篇文章很长,但希望这可以帮助某人做一些看似微不足道的事情 - 将数据从 Azure 中的 API 提取到 Excel 中!