我想查询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时,我得到相同的错误。我搜索过并发现了同样问题的问题here,here,但没有人回答
如何解决此错误?
是否需要拥有本地管理员帐户?
我是否需要在我的B2C应用上设置任何特殊范围以授予我的查询授权?如果有,具体是什么?我试图将范围的不同值交换到MSAL配置中,但没有找到任何有效的值。
此应用需要是多租户吗?
我在access tokens和scopes上找到了资源,但我使用的是Angular 5 / typescript,并且没有.NET中可用的Azure AD Graph Client Library。我无法使用这两种资源。
答案 0 :(得分:3)
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桥接它们(我将其称为User API),如下所示。
在设计时:
在运行时:
答案 1 :(得分:3)
我想写这篇文章是为了帮助那些可能陷入同样困境的人,我试图找到一个基本的方向/理解。我基本上采用了@Chris Pradget描述的工作流程。我对这个问题的初步看法是错误的,我会澄清我的错误在哪里并提供一些背景信息。
我最初的目标是在用户登录Azure / Angular App时引入用户的角色和/或群组声明。当您使用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 explorer和MS Graph Explorer。
我花了一段时间才成功查询了Microsoft Graph,但是当我这样做的时候是MS Graph Explorer,如上所述。我第一次遇到的主要问题是我用自己的帐户查询我的应用程序。只有一些查询工作,甚至那些带来非常有限的信息。直到我重新阅读有关Azure AD Graph API的this article时,才注意到为了查询图表,您需要使用本地租户域的用户ID并且是管理员。当我创建并使用我的租户的管理员(来自该域)时,所有查询都有效。因此,就我的上述问题而言:
1)如何解决此问题["代码":" Authentication_MissingOrMalformed"]错误? 使用本地管理员帐户
2)是否需要拥有本地管理员帐户? 是
3)我的B2C应用程序是否需要设置任何特殊范围才能授予我的查询权限?如果有,具体是什么? 要以ADAL的方式查询MS Graph,请使用Directory.Read Access
4)此应用需要多租户吗? 否
此外,在我的研究中,我发现您可以使用Azure AD角色而不是使用B2C组。具体而言,可以将应用程序角色添加到Azure门户中的Classic Azure AD应用程序清单中。这是一条看起来很有希望的不同路线。我发现this article描述了如何编辑清单以添加应用程序角色。首先,您要向清单添加角色,然后将用户分配给Azure门户中的角色,然后使用ADAL.js库查询用户信息(来自Angular)。使用库登录时,应用程序角色会在获取的令牌上生效。这当然不会使用B2C政策。此外,这可能不言而喻,但是当您登录时,B2C id_token或access_token都不能用于获取Classic Azure AD凭证/令牌。我试着想出其他方法来实现我想要的东西。鉴于2个注册在同一个租户,我认为我可以使用单点登录登录到另一个并保持登录。我没有走得太远。我考虑的另一种方法是使用自定义策略从我的Azure AD经典应用程序中检索数据但是也没有那么远。
当@Chris Padgett提到创建一个"用户api"时,我误解了它。用户api"我认为他的意思是我的经典Azure广告应用注册,它是在Azure门户中设置的,包含我的用户信息,并充当api来检索我的令牌。我以为我首先需要从Angular中的B2C获取访问令牌,然后使用该令牌(仍然在Angular中)来访问我的Azure AD经典注册。从那里我可以拉下我的用户'包括应用程序角色的信息(可通过编辑清单访问)。这不会起作用,因为正如我上面所述,我想通过一次登录来执行此操作,并且您无法在Classic Azure AD应用程序中使用B2C令牌。即使它确实有效,它也需要在我的B2C应用程序之外的经典Azure AD应用程序注册中为用户设置角色,这是我不想做的。有一个应用程序注册的策略和另一个用于管理用户'角色并不优雅。要使其工作,还需要2个登录一个用于B2C,一个用于Classic Azure AD。在这种方法中,感觉这两个应用程序是分开的,我不想在两个平台上分配关注点。因此,最后,在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