如何让.NET Core API借助客户端令牌调用Microsoft Graph API?
嘿,我来一步步帮你理清这些问题,毕竟我之前也做过类似的React+TS + .NET Core + Graph API的集成,踩过不少坑 😊
核心方案:使用On-Behalf-Of (OBO) 流程
这是Azure AD中专门为「后端API代表用户调用下游API(比如Graph)」设计的标准流程,也是最符合安全和权限管控最佳实践的方案。下面逐个解答你的问题:
1. 如何在API端获取权限调用Graph API?
核心就是通过OBO流程,让你的.NET Core API拿着客户端传来的访问令牌,向Azure AD兑换一个专门用于调用Graph API的令牌。具体步骤如下:
- 第一步:配置后端应用的Graph权限
在Azure AD的后端应用注册里,添加Graph API的Delegated权限(比如User.Read、Email.Read),然后完成权限同意(单租户环境下可由管理员统一同意,多租户则可让用户自行同意)。 - 第二步:在.NET Core中集成OBO流程
推荐使用Microsoft.Identity.Web库来简化开发,它已经封装了OBO的令牌获取和刷新逻辑。示例配置如下:
在Program.cs中添加服务:
在builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration) .EnableTokenAcquisitionToCallDownstreamApi() .AddMicrosoftGraph(builder.Configuration.GetSection("Graph")) .AddInMemoryTokenCaches();appsettings.json中配置Graph相关参数:
之后在API控制器中,直接注入"Graph": { "BaseUrl": "https://graph.microsoft.com/v1.0", "Scopes": "User.Read Email.Read" }GraphServiceClient就能调用Graph API了:private readonly GraphServiceClient _graphServiceClient; public UserController(GraphServiceClient graphServiceClient) { _graphServiceClient = graphServiceClient; } [HttpGet("profile")] public async Task<IActionResult> GetUserProfile() { var userInfo = await _graphServiceClient.Me.Request().GetAsync(); return Ok(new { Name = userInfo.DisplayName, Email = userInfo.Mail }); }
2. 是否应让客户端请求含["User.Read", "api://clientId/Test"]的令牌?
完全不需要!客户端只需要请求你的后端API的专属scope(也就是api://clientId/Test)就足够了。Graph API的权限管控应该放在后端应用层面,而不是让客户端直接请求Graph的scope——这样既简化了客户端的逻辑,也避免了客户端拿到Graph令牌后直接调用Graph的安全风险。
3. 注册服务端应用的操作是否正确?
你可以对照以下几点检查:
- 后端应用是否在Azure AD中完成注册,并且添加了Graph API的Delegated权限(且已完成同意);
- 后端应用的「公开API」页面是否配置了正确的scope(比如
api://clientId/Test),且你的客户端应用已经添加了这个scope作为Delegated权限; - 后端应用的身份验证配置中,不需要设置重定向URI(因为是后端API,没有前端跳转的场景)。
如果以上都满足,那你的服务端应用注册就是正确的。
4. 能否让客户端获取仅含["User.Read", "Email.Read"]的Graph令牌并传递给API用于调用?
技术上是可行的,但非常不推荐,原因有三:
- 安全风险:客户端拿到Graph令牌后,完全可以绕过你的后端API,直接调用Graph API,这会破坏你原本的权限管控逻辑;
- 维护成本高:如果后续需要调整Graph的权限(比如新增
Calendars.Read),你需要修改客户端的scope配置,而不是只在后端应用中更新权限; - 令牌生命周期管理麻烦:Graph令牌默认有效期只有1小时,后端如果需要长期调用,得自己处理令牌刷新,而OBO流程中
Microsoft.Identity.Web会自动帮你处理刷新逻辑。
总结
优先采用OBO流程是最优解:客户端只负责获取访问后端API的令牌,后端通过OBO流程兑换Graph令牌并调用API。这种方式既安全,又能集中管理权限,还简化了客户端的开发。
内容的提问来源于stack exchange,提问作者Stam
相关产品推荐
相关产品推荐

