ASP.NET Core Web API调用Microsoft Graph获取Azure AD用户列表遇401未授权问题
我编写了如下ASP.NET Core Web API代码,期望返回Azure AD应用的用户信息列表,该应用已配置委托权限User.ReadBasic.All,且在appsettings.json文件中完成了以下配置:
"TenantId": "", "ClientId": "", "ClientSecret": ""
但即使通过Postman携带令牌发送请求,仍收到“401 Unauthorized”错误。
控制器代码
namespace WebApplication4.Controllers { [Route("api/[controller]")] [ApiController] public class UsersController : ControllerBase { private readonly ITokenAcquisition _tokenAcquisition; public UsersController(ITokenAcquisition tokenAcquisition) { _tokenAcquisition = tokenAcquisition; } [HttpGet] public async Task<IActionResult> GetUsers() { try { // Acquire the access token for Microsoft Graph var token = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { "User.ReadBasic.All", "User.Read" }); // Create the GraphServiceClient with an authentication provider var graphClient = new GraphServiceClient(new AuthProvider(token)); var usersRequestBuilder = graphClient.Users; var users = await usersRequestBuilder .GetAsync(requestConfiguration: request => { request.QueryParameters.Select = new[] { "displayName", "userType", "mail" }; }); return Ok(users); } catch (Exception ex) { return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while fetching users."); } } private class AuthProvider : IAuthenticationProvider { private readonly string _token; public AuthProvider(string token) { _token = token; } public async Task AuthenticateRequestAsync(RequestInformation request, Dictionary<string, object>? additionalAuthenticationContext = null, CancellationToken cancellationToken = default) { // Set the Authorization header request.Headers.Add("Authorization", $"Bearer {_token}"); await Task.CompletedTask; } } } }
我已按下图方式在请求头中添加令牌(
),且确认已获取正确令牌,但发送GET请求时仍返回401未授权,无法获取用户信息。请问我哪里操作有误?
1. 令牌受众不匹配
Postman传入的令牌aud字段必须指向你的API客户端ID(或应用ID URI),如果令牌受众是https://graph.microsoft.com,那它只能用来调用Graph,无法访问你的API。反之,GetAccessTokenForUserAsync获取的令牌必须是针对Graph的,要确保scope参数是https://graph.microsoft.com/User.ReadBasic.All和https://graph.microsoft.com/User.Read(完整的Graph scope)。
2. API未配置Azure AD认证中间件
Web API必须添加Azure AD认证中间件才能验证请求令牌,在Program.cs中补充配置:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); builder.Services.AddAuthorization(); // 正确配置Graph服务依赖 builder.Services.AddMicrosoftGraph(options => { options.Scopes = new[] { "https://graph.microsoft.com/User.ReadBasic.All", "https://graph.microsoft.com/User.Read" }; }) .AddTokenAcquisition();
同时修正appsettings.json的配置结构:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "你的租户ID", "ClientId": "你的API客户端ID", "ClientSecret": "你的客户端密钥", "Audience": "你的API客户端ID" }
3. 自定义认证提供者冗余且易出错
无需手动实现IAuthenticationProvider,使用SDK自带的TokenAcquisitionAuthenticationProvider即可,它能自动处理令牌刷新、格式校验等问题:
var graphClient = new GraphServiceClient(new TokenAcquisitionAuthenticationProvider(_tokenAcquisition, new[] { "https://graph.microsoft.com/User.ReadBasic.All", "https://graph.microsoft.com/User.Read" }));
4. 权限未完成管理员同意
User.ReadBasic.All委托权限需要管理员在Azure AD门户中完成授予管理员同意,普通用户自行同意无法获取读取所有用户信息的权限。同时确认获取令牌的用户拥有对应的访问权限。
5. 查看令牌验证详细日志
在Program.cs开启调试日志,定位401具体原因:
builder.Logging.AddConsole(); builder.Logging.SetMinimumLevel(LogLevel.Debug);
日志会显示令牌验证失败的具体细节,比如签名无效、过期、受众不匹配等。
内容的提问来源于stack exchange,提问作者Madhura D

