You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure C#无弹窗获取用户令牌并查询用户组的方案咨询

解决方案说明

为什么之前调用接口报错

你用ConfidentialClientApplicationBuilder获取的是应用权限令牌——这类令牌代表应用本身执行操作,没有绑定具体用户上下文。而/me接口依赖当前用户的上下文才能识别要查询的对象,所以用应用权限令牌调用必然返回错误。

可行方案分两种场景

场景1:查询特定已知用户的组信息(无需用户交互)

如果你的WebAPI只需查询某个固定用户的组,直接用应用权限流即可,调整接口调用路径:

  1. 在Azure AD应用注册中添加应用权限(比如Group.Read.All),并联系租户管理员完成权限同意
  2. 调用Graph API的users/{userPrincipalName}/memberOf接口(替换{userPrincipalName}为目标用户的邮箱或UPN)
  3. C#代码示例:
using Microsoft.Identity.Client;
using System.Net.Http.Headers;
using System.Text.Json;

var tenantId = "你的tenant_id";
var clientId = "你的client_id";
var clientSecret = "你的client_secret";
var targetUserUpn = "目标用户的UPN(比如user@domain.com)";

// 构建客户端并获取应用权限令牌
var app = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithClientSecret(clientSecret)
    .WithTenantId(tenantId)
    .Build();

var scopes = new[] { "https://graph.microsoft.com/.default" };
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();

// 调用Graph API查询用户组
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

var response = await httpClient.GetAsync($"https://graph.microsoft.com/v1.0/users/{targetUserUpn}/memberOf");
response.EnsureSuccessStatusCode();

var content = await response.Content.ReadAsStringAsync();
var groups = JsonSerializer.Deserialize<JsonElement>(content);
// 处理返回的组数据

场景2:代表当前访问WebAPI的用户查询其自身组信息

如果WebAPI需要处理已登录用户的请求,用On-Behalf-Of(OBO)流:

  1. 前端先通过授权码流获取用户的访问令牌(这一步的弹窗在前端完成,后端WebAPI无弹窗)
  2. 前端将令牌传给你的WebAPI,WebAPI用OBO流换取针对Graph API的令牌
  3. 调用/me/memberOf接口查询用户自身组
  4. C#代码示例(WebAPI中的逻辑):
using Microsoft.Identity.Client;
using System.Net.Http.Headers;
using System.Text.Json;

var tenantId = "你的tenant_id";
var clientId = "你的client_id";
var clientSecret = "你的client_secret";
// 从请求头中获取前端传入的用户令牌
var userToken = Request.Headers.Authorization.Parameter;

// 构建客户端并执行OBO流
var app = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithClientSecret(clientSecret)
    .WithTenantId(tenantId)
    .Build();

var scopes = new[] { "https://graph.microsoft.com/Group.Read.All" };
var result = await app.AcquireTokenOnBehalfOf(scopes, new UserAssertion(userToken)).ExecuteAsync();

// 调用Graph API查询当前用户组
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

var response = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/me/memberOf");
response.EnsureSuccessStatusCode();

var content = await response.Content.ReadAsStringAsync();
var groups = JsonSerializer.Deserialize<JsonElement>(content);
// 处理返回的组数据

注意事项

  • 应用权限需要租户管理员同意,委派权限若为“管理员同意”类型也需管理员操作,否则普通用户授权即可
  • 避免使用资源所有者密码凭证(ROPC)流,该方式安全性低,Microsoft不推荐用于生产环境

内容的提问来源于stack exchange,提问作者Baz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:15:56