Power Query/PowerBI 连接到使用 AAD 保护的自定义 oDATA 源

Ale*_*lie 2 c# asp.net-web-api azure-active-directory powerquery powerbi

我使用 ASP.NET Web API 创建了一个自定义 OData 源。此服务使用 Azure Active Directory 进行身份验证配置。我目前遇到的问题是当我尝试将 Power BI 或 Power Query 连接到 OData 源时。输入凭据后,我收到以下错误:

Invalid_resource:AADSTS50001:在名为 XXX.onmicrosoft.com 的租户中找不到名为https://localhost:44320的应用程序。如果应用程序尚未由租户的管理员安装或租户中的任何用户未同意,则可能会发生这种情况。您可能将身份验证请求发送给了错误的租户。

我很确定我已经正确配置了 AAD,因为我可以通过 Web 浏览器毫无问题地进行连接。我不确定是否可以与 Power Query 连接,因为我在各种论坛中看到了相互矛盾的帖子!

任何帮助将不胜感激。

Jam*_*ose 7

我在尝试使用 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 中执行数据 > 从 Web > https://api.myapp.net/Products并选择“组织帐户”并单击“登录”,出现此错误:

无法连接,因为不支持凭据类型

对此有两种不同的修复:

1. 在所有 401 上返回 WWW-Authenticate 响应头

如果您在代码中使用 owin 中间件在 API 上启用了 AAD,那么您需要确保服务在给客户端的 401 响应中返回正确的 ?WWW-Authenticate 标头,特别是我们必须指定 AAD 登录端点作为授权uri,例如:

WWW-Authenticate: Bearer realm="", 
authorization_uri="https://login.microsoftonline.com/<<tenant id of your users>>"
Run Code Online (Sandbox Code Playgroud)

请参阅:建议此解决方案的此 TechNet 问题

2. 在 Azure 门户中为 API 应用服务开启 AAD 身份验证

  • 或者,在托管应用服务本身的租户的 Azure 门户中
  • 转到应用服务并找到 API 应用服务
  • 在身份验证/授权中打开应用服务身份验证
  • 对于“未经身份验证时采取的操作”,选择“使用 Azure Active Directory 登录”
  • 在“身份验证提供程序”下单击“Azure Active Directory”并选择“高级”设置
  • 在“客户端 ID”下输入 API 应用程序注册的应用程序 ID
  • 在“颁发者 URL”下,输入 API 用户源自的租户的登录端点
  • 在“允许的令牌受众”下,确保您已添加 API 的实际网址,例如https://api.myapp.net
  • 保存更改

基本上这个配置在这里描述

问题 2 - 应用注册

现在返回 Excel,当您单击查询上的登录时,将打开一个弹出窗口并将您带到您配置的租户的 Microsoft 登录页面。当您输入凭据并登录时,您可能会收到此错误(问题中的错误):

在此处输入图片说明

要解决此问题,您需要确保应用程序已正确注册到 AAD。

这是如何...

  • 在注册应用程序的租户的 Azure 门户中
  • 转到 Azure Active Directory > App Registrations 并找到 API 服务的注册
  • 编辑清单并确保在 identifierUris 列表中配置了实际部署的 API URL,例如?https://api.myapp.net(会有一个已经配置好的Azure内置URL)
WWW-Authenticate: Bearer realm="", 
authorization_uri="https://login.microsoftonline.com/<<tenant id of your users>>"
Run Code Online (Sandbox Code Playgroud)
  • 如果应用程序是多租户的,则需要确保此 URL 中使用的域已通过 Azure 验证
  • 您还必须确保user_impersonation范围可用于应用程序:
{
  "identifierUris": [
    "https://api.myapp.net",
    "https://<mytenant>.onmicrosoft.com/<myappregname>"
  ]
}
Run Code Online (Sandbox Code Playgroud)
  • 保存更改。

问题 3 - 允许的令牌受众

现在回到 Excel,您应该能够通过登录,但是当单击“连接”时,您可能会收到此错误:

无法验证

现在查看 fiddler,您将看到 AAD 登录有效并返回一个令牌,但是当将其发送到 API 时,您会得到 401。

如果您通过代码而不是通过 Azure 门户启用了 AAD,这只是一个问题(请参阅上面的问题 1!)。要修复它,您需要确保传递给 owin 中间件的TokenValidationParameters ValidAudience设置为已部署 API 的实际 url。

运行查询

完成所有这些设置后,一切都应该可以正常工作了,回到 Excel 中......

  • 单击登录,将打开一个弹出窗口并将您带到您配置的租户的 Microsoft 登录页面,使用您的凭据登录
  • 点击连接
  • 然后 PowerQuery 编辑器将打开并显示从 API 检索到的数据
  • 单击“开始”>“高级编辑器”,您将能够查看原始查询 - 这是PowerQuery 使用的查询语言?M-query 语法,在我的情况下,数据是一个平面数组,所以这就足够了:
{
  "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"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)
  • 单击关闭并加载将数据返回到 Excel 工作表

这是如何工作的

如果您关心(并且仍在阅读本文!),它的工作方式似乎是:

  1. PowerQuery 在“Microsoft PowerQuery For Excel”内置应用程序下请求访问您的 API(客户端 ID a672d62c-fc7b-4e81-a576-e60dc46e951d)
  2. 当您登录时,AADuser_impersonation将 API 上的动态范围(由资源 URL https://api.myapp.net标识)授予“Microsoft PowerQuery For Excel”应用程序
  3. 您可以通过转到企业应用程序,检查 Microsoft 应用程序并搜索 Microsoft PowerQuery For Excel 来在门户中看到这一点

在此处输入图片说明

在此处输入图片说明

抱歉这篇长文章,但希望这可以帮助某人做一些看似微不足道的事情 - 将数据从 Azure 中的 API 提取到 Excel 中!