【问题标题】:Azure Graph API, Angular, Get users GroupsAzure Graph API、Angular、获取用户组
【发布时间】:2018-01-11 17:05:53
【问题描述】:

我想查询 Azure AD Graph API 以从已注册的 Azure B2C 应用中检索登录用户的组声明。我调用的应用是 Angular 5 SPA。

在试用 Azure Active Directory 和 adal-angular4 后,我成功检索了用户的自定义 角色声明。为此,我注册了一个 Azure AD 应用程序,设置所需的权限范围,将自定义角色添加到应用程序的清单,将用户添加到应用程序,并为用户设置自定义角色。然后,我将我新注册的应用程序的应用程序 ID 和租户用于 adal-angular4 配置。当我查询端点时,我得到了包含角色声明的令牌。它运作良好。当我更改它在令牌中显示的角色时。

这个角色声明对我来说已经足够了,但它需要两次登录,一次用于我的 B2C 应用程序,一次用于我的其他注册应用程序。我不认为我可以对两者使用相同的令牌。

为了只有一次登录,我想直接查询Azure B2C。我听说它不提供像 Azure Active Directory 那样查询用户角色的功能,并且已被指示使用用户组。我还看过文档,并被告知我需要使用 Azure Graph API,因为 Microsoft Graph 尚未实现查询此信息的功能。

我尝试遵循与 AAD 一起使用的类似 B2C 路径。我创建了一个组并将一个用户添加到该组。我尝试使用 MSAL.js 通过 Azure Graph API 端点 https://graph.windows.net/myorganization/users?api-version=1.6 访问我的 B2C 应用程序的信息,但我收到错误 "code": "Authentication_MissingOrMalformed"。我验证了一个令牌已由 MSAL 检索并被添加到请求中。当我将 url 更改为无效的 url 时,我得到了同样的错误。我已经搜索并找到了相同问题的问题herehere,但没有答案

如何解决此错误?

是否需要拥有本地管理员帐户?

是否需要在我的 B2C 应用程序上设置任何特殊的范围来为我的查询授予授权?如果有,它们具体是什么?我尝试将范围的不同值交换到 MSAL 配置中,但没有找到任何可行的方法。

此应用需要多租户吗?

我在 access tokensscopes 上找到了资源,但我使用的是 Angular 5 / typescript,并且没有 .NET 中可用的 Azure AD Graph 客户端库。这两种资源我都无法使用。

【问题讨论】:

标签: angular azure azure-ad-b2c azure-ad-graph-api msal


【解决方案1】:

我想写这篇文章来帮助那些可能陷入我试图找到基本方向/理解的同一条路的人。我基本上采用了@Chris Pradget 描述的工作流程。不过我最初对这个问题的看法是错误的,我会澄清我的错误在哪里,并提供一些背景信息。

我最初的目标是在用户登录到我的 Azure / Angular 应用程序时带来用户的角色和/或组声明。当您使用 Azure B2C 登录以获取策略时,Azure 没有简单的方法来执行此操作。 (在某些方面,Firebase 似乎让这一切变得简单)。

经过大量研究并没有真正理解大局,我看到了似乎相互矛盾的信息,需要一些时间来整理。最终我找到了我正在寻找的信息,即我不能只登录一次。

(请注意,我将我的经典 Azure AD 注册应用称为“应用注册”,只是为了与 Azure 门户中的代码实现和配置集区分开来)

进行了大量的实验,但我想出了一些似乎可行的方法。我基本上检索了 3 个令牌,其中 2 个在 Angular 中使用 MSAL.js,一个在 .NET 中使用 ADAL for Microsoft Graph。 Angular 中的一个是用于初始登录(MSAL 客户端的 loginRedirect 调用)以检索 id_token,另一个是我使用该令牌以及 aquireTokenSlient 函数检索来检索 access_token。我将它发送到我的 .NET Core 后端,在那里我使用传入令牌中的用户 ID 作为 request to Microsoft Graph 中的资源 ID 来获取我的组声明,然后我 crafted my own JWT token 将声明发送回 Angular 用于我的路由守卫.

我研究中的注意事项:

Azure AD Graph 与 Microsoft Graph 拉取用户组:关于使用哪一个的信息存在冲突,有人说 Microsoft Graph 因为 Azure Graph 已被弃用,但其他人说 Azure Graph 因为 MS Graph 尚未涵盖所有基础.经过实验,我发现我能够从 MS Graph 中拉出一个用户的组。鉴于这一点以及 MS Graph 更新的事实,我选择了 MS Graph。为了对图表进行实验,我同时使用了 Azure Graph explorerMS Graph Explorer

我花了一些时间才成功查询 Microsoft Graph,但当我这样做时是通过MS Graph Explorer 进行的,如上所述。我第一次遇到的主要问题是当我用自己的帐户查询我的应用程序时。只有一些查询有效,甚至那些带回的信息也非常有限。直到我重新阅读 this article 关于 Azure AD Graph API 时,我才注意到为了查询 Graph,您需要使用租户域本地的用户 ID 并且是管理员。当我创建和使用租户的管理员(来自该域)时,所有查询都有效。所以就我上面的问题而言:

1) 如何修复此 ["code": "Authentication_MissingOrMalformed"] 错误? 使用本地管理员帐户

2) 是否需要拥有本地管理员帐户? 是的

3) 是否需要在我的 B2C 应用程序上设置任何特殊范围来授予对我的查询的授权?如果有,具体是什么? 要使用 ADAL 以您想要的方式查询 MS Graph,请使用 Directory.Read Access

4) 这个应用需要多租户吗? 没有

此外,在我的研究中,我发现您可以使用 Azure AD 角色,而不是使用 B2C 组。具体来说,可以将应用程序角色添加到 Azure 门户中的经典 Azure AD 应用程序清单。这是一条不同的路线,对我来说很有希望。我发现this article 描述了如何编辑清单以添加应用程序角色。首先将角色添加到清单,然后将用户分配给 Azure 门户中的角色,然后使用 ADAL.js 库查询用户信息(来自 Angular)。当您使用该库登录时,应用程序角色会在获取的令牌上下降。这当然不使用 B2C 策略。这也是不言而喻的,但是当您登录时,B2C id_token 或 access_token 都不能用于获取经典 Azure AD 凭据/令牌。我试着想其他方法来完成我想要的。鉴于这两个注册在同一个租户中,我想我可以使用单点登录来登录其中一个并保持另一个登录状态。我没有走多远。我考虑过的另一种方法是使用自定义策略从我的 Azure AD 经典应用程序中检索数据,但也没有成功。

此外,当@Chris Padgett 提到创建“用户 api”时,我误解了它。我认为“用户 api”是指我在 Azure 门户中设置的经典 Azure 广告应用注册,其中包含我的用户信息,并充当检索我的令牌的 api。我认为我首先需要在 Angular 中从 B2C 获取访问令牌,然后使用该令牌(仍在 Angular 中)访问我的 Azure AD 经典注册。从那里我将能够下拉我的用户信息,包括应用程序角色(通过编辑清单可以访问)。这是行不通的,因为正如我上面所说,我想通过一次登录来执行此操作,并且您不能在经典 Azure AD 应用程序中使用 B2C 令牌。即使它确实有效,它也需要在我不想做的 B2C 应用程序之外的经典 Azure AD 应用程序注册中为用户设置角色。为策略注册一个应用程序并为管理用户角色注册另一个应用程序并不是很优雅。让它工作还需要 2 个登录,一个用于 B2C,一个用于 Classic Azure AD。在这种方法中,感觉这 2 个应用程序是独立的,我不想在 2 个平台上划分关注点。所以,最终在 Angular 中使用 B2C 登录,然后使用 MS Graph 访问服务器拉取用户组的场景是一个更好的方案。后端应用程序只需要登录一次,独立于访问它的用户,这意味着用户不需要登录两次。它还将我的信息整合到我的 B2C 应用注册中。

我认为 Azure 可能最终会在其 id_tokens 上提供组和/或角色,但我认为此信息同时可能对人们有所帮助。此外,以下是我提出的其他相关问题的链接,这些问题有助于指导我的研究:

Learning that I needed to use MSAL.js over ADAL.js in order to use B2C Policies.

A similar question I asked about querying MS Graph and getting a limited response

【讨论】:

  • 感谢您提供详细信息。很难找到好的解释。我有一个问题,你是如何处理 idtoken 刷新/更新的?我正在使用 msal 来获取 Idtoken,并且 idtoken 在 60 分钟内过期,这会导致用户重新登录。另外,我们如何设置 idtoken 的过期时间?任何帮助将不胜感激!
  • 抱歉,我还没来得及刷新 id 令牌。
【解决方案2】:

Azure AD B2C 使用 Azure AD v2.0 端点颁发令牌:

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

Azure AD Graph API 需要使用 Azure AD v1.0 端点颁发的令牌:

https://login.microsoftonline.com/{tenant}/oauth2/token

对于访问 Azure AD Graph API 的单页应用程序,您必须使用代理 API(我将其称为用户 API)桥接它们,如下所示。

在设计时:

  1. 使用 Azure AD B2C 门户注册单页应用程序。
  2. Register the User API using the Azure AD portalgrant the Read directory data permission

在运行时:

  1. 单页应用程序将最终用户重定向到 Azure AD B2C v2.0 端点以进行登录。 Azure AD B2C 颁发一个包含用户标识符的 ID 令牌。
  2. 单页应用程序使用此 ID 令牌调用用户 API。用户 API 验证 ID 令牌。
  3. 用户 API 使用在设计时在步骤 2 中创建的应用程序凭据从 Azure AD v1.0 端点获取访问令牌。
  4. 用户 API 调用 Azure AD Graph API,传递在步骤 2 中收到的用户标识符和在步骤 3 中发布的访问令牌,查询组成员资格,然后将这些返回给单页应用程序.

【讨论】:

  • 我正在使用 MSAL.js,并且一直在为我的登录策略查询以下端点:'login.microsoftonline.com/tfp/${tenant}/${signUpSignInPolicy}'。登录后,用户将使用令牌返回到应用程序。我应该使用此令牌登录用户 API 吗?我已经能够使用 adal-angular4 从用户 API 单独登录来提取数据,我相信它使用了上面提到的 Azure AD v1.0 端点(与 Fiddler 一起检查)。我可以尝试通过替换令牌来避免第二次登录。我使用 Postman 手动构建这些请求,但遇到了麻烦。
  • 嗨@afriedman111。 Angular 应用程序应该获取“策略”令牌,然后将其发送到用户 API。用户 API 应该对其进行验证。如果有效,则用户 API 应使用其应用程序凭据获取“v1.0”令牌,并将其传递给 Graph API 以检索用户组。
  • 第 1 步由 Azure AD B2C 颁发的 ID 令牌不能用于在第 4 步与 Azure AD Graph API 交互。用户 API 必须验证 ID 令牌(代表用户身份)从单页应用程序传递,然后获取可以传递给 Azure AD Graph API 的另一个访问令牌(表示其自己的身份)。是的,您可以另外创建自定义策略,调用您的用户 API(使用 HTTP 基本或客户端证书身份验证进行保护)以通过 Azure AD Graph API 检索组声明。
  • 嗨 @goneos 你的意思是在第 3 步获取访问令牌吗?
  • 在第 3 步,建议用户 API(即服务器端代码)正在与 Azure AD 和 Azure AD Graph API 交互,因此您应该不会遇到任何 CORS 问题。跨度>
猜你喜欢
  • 1970-01-01
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多