SPFX(Teams)后端如何通过OBO流调用代表登录用户的Graph API?
解决方案
你需要使用Azure AD的代表用户(On-Behalf-Of,简称OBO)流实现需求,无需用户二次登录。该流允许你的后端服务使用前端传入的用户令牌,换取代表同一用户身份的Graph API访问令牌。
前置配置(Azure应用注册)
- 给后端服务对应的Azure AD应用注册添加你需要调用的Graph API委托权限,并完成租户管理员全局同意
- 为后端应用注册暴露API,生成自定义作用域(例如
api://<后端应用ID>/access_as_user) - 确认SPFX对应的Azure AD应用注册已被授予调用后端自定义作用域的权限
后端代码改造
替换原有的客户端凭证流逻辑,改为OBO流实现,示例代码如下:
using Microsoft.Identity.Client; using Microsoft.Graph; using System.Net.Http.Headers; // 1. 从请求头获取前端传入的用户访问令牌 string incomingToken = Request.Headers["Authorization"].ToString().Replace("Bearer ", string.Empty); var userAssertion = new UserAssertion(incomingToken); // 2. 构造机密客户端应用 IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder .Create(clientId) .WithTenantId(tenantId) .WithClientSecret(clientSecret) .Build(); // 3. 使用OBO流换取Graph访问令牌,替换为实际需要的Graph权限 string[] graphScopes = new[] { "https://graph.microsoft.com/User.Read", "https://graph.microsoft.com/Sites.Read.All" }; var result = await confidentialClientApplication.AcquireTokenOnBehalfOf(graphScopes, userAssertion).ExecuteAsync(); // 4. 生成带用户身份的Graph客户端 var authProvider = new DelegateAuthenticationProvider((requestMessage) => { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); return Task.CompletedTask; }); var graphClient = new GraphServiceClient(authProvider);
常见注意事项
- OBO流仅支持委托权限,不能搭配应用权限使用,否则无法携带用户身份
- 前端调用后端时必须传入
backendToken(受众为后端应用的令牌),不能传入Graph令牌,否则OBO流校验会失败 - 建议将后端应用注册清单中的
accessTokenAcceptedVersion设置为2,避免令牌版本不匹配导致的报错 - 后端换取的Graph令牌权限范围仅包含你提前配置并完成管理员同意的委托权限,无需用户额外授权
内容的提问来源于stack exchange,提问作者MrJohn1985
相关产品推荐
相关产品推荐

