如何代表(OBO)流程实施个人Microsoft帐户(MSA)?

时间:2019-12-04 20:31:42

标签: azure-active-directory msal

我有一个单页Javascript应用程序(SPA)。我有一个使用TypeScript / NodeJS的中间层Azure函数服务。 SPA允许用户登录,并根据需要联系中间层服务以从MS Graph检索日历数据。然后,中间层需要能够代表用户再次定期检索该日历数据,而无需来自客户端的其他明确请求。

我需要同时支持Azure AD帐户个人MSA帐户。我有一个针对SPA的AAD应用注册,一个针对中层服务的注册。对于Azure AD帐户,这一切“都行得通”,因为中间层从客户端接收访问令牌,将其交换为AAD的访问令牌+刷新令牌,然后使用其访问令牌从MS Graph API检索数据。通过使用作为OBO流一部分的刷新令牌来定期刷新。

我知道使用个人MSA帐户进行这项工作更具挑战性,因为缺乏联合同意。我可以找到有关如何使用MSA进行工作的唯一建议是在this page的“使用单个应用程序”部分下。但是,我似乎无法完成这项工作。

如果我更改了SPA,以要求(在MSAL库上)调用AcquisitionTokenSilent时请求中间层需要的所有相同范围(https://graph.microsoft.com/Calendars.Read openid个人资料电子邮件offline_access),则会显示正确的同意对话框,但访问令牌I回来不是JWT。我知道这是可以预期的(由于this page顶部的“重要”注释),但是当我尝试对中间层进行OBO流程时,这会引起问题。如果我使用该非JWT访问令牌,请将其发送到我的中间层服务(该中间层服务现在使用与SPA相同的AAD应用程序注册来标识自己),然后尝试为OBO流调用AAD端点,则出现此错误:

AADSTS50027: JWT token is invalid or malformed.
Trace ID: a3647c0e-e7f5-4919-a457-1bd1e951f501
Correlation ID: a44f9292-1ba0-43b7-aafe-0a77e5adbc35
Timestamp: 2019-12-04 18:52:58Z

...所以显然是期待JWT。

是否有一种方法可以使此OBO流程与个人MSA一起使用?还是在带有需要刷新令牌的中间层使用个人MSA时,这种OBO流程不是正确的做法(这样它可以代表用户定期调用MS Graph API)?如果这不是正确的选择,那么我的中间层如何才能获得有效的刷新令牌,以便它可以定期检索新的访问令牌?

注意:我已经阅读了this的帖子,但似乎并没有解决我遇到的问题-我知道,常见的OBO模式不能同时用于AAD和个人MSA帐户(令人沮丧的)但是我无法使任何个人MSA OBO流正常工作,暂时忽略了我可能能够在Azure AD和个人MSA OBO流之间共享多少代码(如果有的话)。

谢谢!

1 个答案:

答案 0 :(得分:0)

对于您所陈述的问题,如果前端可以同时获得Graph的AAD和MSA用户的成功同意,则您可能无需OBO呼叫即可获得所需的信息。

我建议您利用MSAL的令牌缓存功能来获取您想要的内容。

MSAL提供了从外部cache tokens(特别是在您使用刷新令牌的情况下)的功能。 here提供了详细的演练。

AAD V2允许将一个应用程序ID应用于同一应用程序的多个实例,尤其是在它们共享同一拓扑部署单元的情况下,尤其推荐使用该ID。

您的应用的前端和后端具有相同的应用ID。

  1. 为应用程序实现外部令牌缓存。
  2. 针对相同的令牌缓存初始化前端和后端。
  3. 确保前端获得所有必需范围的必要同意。
  4. 后端可以随时从缓存中获取consented用户的AT。 MSAL抽象了使用RT获得新AT的内部过程。可能是因为应用ID相同。
  5. 如果您的后端中的MSAL失败(并且定期更新(例如用户更改其密码)时),请将此事件保存在某处并建议用户再次在前端进行登录过程。