azure - 代表当前登录到单独 Web 客户端的用户从 API 访问 MS Graph
问题描述
我正在开发一个 API(ASP.NET Core),可以通过单独托管的 Web 客户端(React)访问,两者都作为应用服务托管在 azure 上。客户端应用程序必须具有基于 azure Ad 的身份验证(单租户,最好由基于 aad 的 azure auth 保护)。当用户登录客户端时,API 必须代表用户有权访问 MS Graph。显然这两个资源都必须得到保护,我已经尝试在两个应用程序服务上使用基于 AAD 的 azure auth,但是我无法在这种方法中使用从 auth 获得的令牌到 API 端的 ADD 获取到 MsGraph 的令牌。
问题是,如何避免使用来自客户端的 azure aad auth 令牌将令牌传递给 MsGraph,并仅基于来自 aad auth 的令牌获取 msGraph 的令牌,同时只有一个地方供用户登录并确保两个应用程序服务的安全?
我在 Api 端为 MsGraph 使用 nugget 来与 MsGraph 交互。我还没有找到任何涉及此特定案例的样本。
解决方案
场景:您的应用程序的 Web API(受 Azure AD 保护)从客户端应用程序 (React) 接收身份验证令牌,并且需要代表已登录用户调用下游 Web API (Microsoft Graph)。
Microsoft Docs 上的概念文档:您的方案完全符合 OAuth 2.0 代表流程,如 Microsoft Docs for Azure AD中所述 服务到服务调用在代表流程中使用委派的用户身份
代码示例:
- 代表用户的服务到服务调用(来自 GitHub 上的 Azure-Samples)
- 代表用户从 Web API 调用下游 Web API(来自 GitHub 上的 Azure-Samples)
- 在 ASP.NET Core 2.0 API 中使用 Azure AD On-Behalf-Of 流(不是直接的 Microsoft 示例,而是来自 Joonas W 的博客,他是 MVP)
重要代码
这就是你如何使用已经传入的令牌来获取一个新令牌,用它代表用户从你的 Web API 调用 Microsoft Graph API。
准备用户断言:
ClientCredential clientCred = new ClientCredential(clientId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
获取 Microsoft Graph 的令牌:
result = await authContext.AcquireTokenAsync(graphResourceId, clientCred, userAssertion);
推荐阅读
- excel - 如何在mule 3中将新工作表附加到现有的excel文件
- java - 将 java 方法转换为 HTTP 请求
- clojure - 如何在 Clojure 的嵌套数组映射中找到键的路径?
- reactjs - 反应下拉值
- python - 检查 Jupyter notebook 中命令的 CPU 利用率
- sql - 更新前的 Firebird 触发器(使用时间戳更新列)
- typescript - 未实例化类的接口
- heroku - Cloudflare CDN 背后的 Heroku 应用程序在以色列出现 DNS 错误 1016 大约一个月
- ios - 如何在 SwiftUI for macOS Catalyst 中更改拆分导航视图的分隔线颜色?
- webrtc - webrtc和dropzone.js,在iOs Safari上当客人尝试上传摄像头时会出现黑屏,这是怎么回事?