Microsoft Graph SDK中代表用户身份验证的实现问题
基于Microsoft Graph SDK 5.x的代表流(On-Behalf-Of)实现方案
针对你提到的身份验证流程,尤其是在Microsoft Graph SDK 5.3.0+中替换已移除的DelegateAuthenticationProvider,以下是符合最新SDK规范的代码实现及配置要点:
一、跳过步骤3:直接用步骤1的用户令牌调用Microsoft Graph
所需NuGet包
Install-Package Microsoft.Graph Install-Package Azure.Identity
代码实现
using Microsoft.Graph; using Azure.Identity; // 从Web应用的身份验证上下文获取步骤1生成的用户访问令牌 string userAccessToken = "<步骤1获取的Bearer令牌>"; // 初始化代表流凭据 var oboCredential = new OnBehalfOfCredential( tenantId: "<你的Azure AD租户ID>", clientId: "<API B的应用注册客户端ID>", clientSecret: "<API B的应用注册客户端密码>", userAssertionToken: userAccessToken); // 创建Graph服务客户端 var graphClient = new GraphServiceClient(oboCredential); // 示例:调用Microsoft Graph获取SharePoint站点信息 try { var targetSite = await graphClient.Sites["<SharePoint站点ID>"].GetAsync(); Console.WriteLine($"站点名称:{targetSite.Name}"); } catch (Exception ex) { Console.WriteLine($"Graph调用失败:{ex.Message}"); }
注意事项
- API B的应用注册必须添加Microsoft Graph的委托权限(如
Sites.Read.All),并完成管理员同意授权 - 步骤1的用户令牌需包含
scp声明,且声明中包含API B所需的权限范围 - API B需配置为机密客户端(拥有客户端密码或证书)
二、完整流程:API A → API B → Microsoft Graph(代表流传递)
API A端:获取调用API B的代表令牌并发起请求
using Azure.Identity; using System.Net.Http.Headers; // 从请求头解析步骤2传递的用户令牌 string userAccessToken = Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); // 初始化代表流凭据,用于获取API B的访问令牌 var oboCredentialForApiB = new OnBehalfOfCredential( tenantId: "<你的Azure AD租户ID>", clientId: "<API A的应用注册客户端ID>", clientSecret: "<API A的应用注册客户端密码>", userAssertionToken: userAccessToken); // 定义API B的权限范围(需与API A应用注册中配置的权限一致) var tokenContext = new TokenRequestContext(new[] { "<API B的应用ID URI>/access_as_user" }); var apiBToken = await oboCredentialForApiB.GetTokenAsync(tokenContext, CancellationToken.None); // 调用API B并携带代表令牌 using var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiBToken.Token); var apiResponse = await httpClient.GetAsync("<API B的业务端点URL>");
API B端:用API A传递的令牌调用Microsoft Graph
using Microsoft.Graph; using Azure.Identity; // 从请求头解析API A传递的代表令牌 string apiAToken = Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); // 初始化Graph调用的代表流凭据 var oboCredential = new OnBehalfOfCredential( tenantId: "<你的Azure AD租户ID>", clientId: "<API B的应用注册客户端ID>", clientSecret: "<API B的应用注册客户端密码>", userAssertionToken: apiAToken); var graphClient = new GraphServiceClient(oboCredential); // 示例:获取SharePoint站点根目录文件列表 var driveItems = await graphClient.Sites["<SharePoint站点ID>"].Drive.Root.Children.GetAsync();
核心配置要求
- 应用注册配置
- Web应用、API A、API B均需注册为Azure AD机密客户端(配置客户端密码或证书)
- API A的应用注册需添加API B的委托权限,并完成管理员同意
- API B的应用注册需添加Microsoft Graph的委托权限,并完成管理员同意
- 令牌验证
- 所有传递的令牌必须包含
scp(委托权限范围)和azp(客户端ID)声明 - 令牌的受众(
aud)需与目标API的应用ID URI匹配
- 所有传递的令牌必须包含
内容的提问来源于stack exchange,提问作者igorjrr
相关产品推荐
相关产品推荐

