.NET Core C# Web API调用Graph API返回401未授权问题如何解决
问题根因梳理
你的401错误根本不是调用Graph API触发的,是调用你自己的.NET Web API时就触发了,核心错误点有4个:
- 令牌受众不匹配:你前端当前调用
acquireTokenSilent获取的是Graph API的访问令牌,该令牌的aud(受众)声明为graph.microsoft.com,完全无法用于验证你自己的.NET Web API,API的JWT验证模块会直接拒绝该令牌返回401 - 身份验证信息传递错误:你把令牌塞进了请求体,而.NET Web API的JWT验证默认从
Authorization请求头提取Bearer令牌,根本获取不到可用于验证的令牌,直接触发401 - 用法冗余:你已经配置了Microsoft.Identity.Web的On-Behalf-Of流能力,完全不需要前端获取Graph令牌再传给后端,后端可以自行兑换Graph的访问令牌
- 参数绑定错误:前端提交的是FormData格式数据,后端接口用
[FromBody]接收JSON格式参数,参数绑定失败也会触发权限验证前置的4xx错误
解决步骤
1. 调整前端MSAL配置和请求逻辑
首先在Azure门户的Web API应用注册中,暴露API并新增作用域,示例为api://<你的Web API Client ID>/access_as_user,再调整前端代码:
if (!graphData && inProgress === InteractionStatus.None) { // 这里请求的scope改为你自己Web API暴露的作用域,不再请求Graph的scope const apiAccessTokenRequest = { scopes: ["api://<你的Web API客户端ID>/access_as_user"] } instance.acquireTokenSilent(apiAccessTokenRequest).then((accessTokenResponse) => { const apiAccessToken = accessTokenResponse.accessToken; // 调用Web API时把令牌放到Authorization请求头,不需要再往请求体塞access_token fetch('/api/profile', { method: 'POST', headers: { 'Authorization': `Bearer ${apiAccessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ /* 你要传递的其他业务参数 */ }) }) }).catch((error) => { console.log(error); }) }
2. 调整后端配置和接口逻辑
首先确认appsettings.json配置正确:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "<你的租户ID>", "ClientId": "<你的Web API的客户端ID>", "ClientSecret": "<你的Web API的客户端密钥>" }, "DownstreamApi": { "BaseUrl": "https://graph.microsoft.com/v1.0", "Scopes": "User.Read" // 替换为你实际需要的Graph作用域 }
再调整ProfileController代码,你注入的GraphServiceClient已经由Microsoft.Identity.Web自动处理On-Behalf-Of流兑换令牌,不需要自己加授权头:
[Authorize] // 必须加Authorize特性触发身份验证 [HttpPost] public async Task<ActionResult> PostProfileItem([FromBody] 你的业务参数DTO dto) { HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi); try { User profile = await _graphServiceClient.Me.Request().GetAsync(); return Ok(profile); } catch (Exception ex) { return StatusCode(500, ex.Message); } }
你原来的SetProfileDTO可以直接删除,不需要接收前端传递的access_token。
3. 验证Azure应用注册配置
- 确认前端应用注册的API权限列表中,已经添加了你Web API暴露的作用域,且已经授予管理员同意
- 确认Web API应用注册的API权限列表中,已经添加了需要的Graph权限,且已经授予管理员同意
- 确认Web API应用注册的「已知客户端应用」列表中,添加了前端应用的客户端ID,避免授权同意提示问题
内容的提问来源于stack exchange,提问作者Shipra Sharma
相关产品推荐
相关产品推荐

