ASP.NET Core 3.1 Web API Azure AD认证401错误求助
看起来你遇到的是Azure AD JWT Bearer认证中典型的令牌验证不通过问题,401错误通常和令牌受众、权限配置或者API端的验证规则不匹配有关。我来帮你一步步梳理排查方向:
1. 确认JWT令牌的受众(Audience)是否匹配
首先,你可以用jwt.ms解析Angular获取到的访问令牌,重点查看aud字段是否和Web API的ClientId(或API的应用程序ID URI,比如api://your-client-id)完全一致。
如果令牌的受众是API的应用程序ID URI而非纯ClientId,需要在API端显式配置验证规则,修改Startup.cs中的JwtBearer配置:
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options => { options.Authority += "/v2.0"; // 指定API的有效受众,替换为你的ClientId或应用程序ID URI options.TokenValidationParameters.ValidAudience = Configuration["AzureActiveDirectory:ClientId"]; // 如果需要支持多个受众,可使用数组: // options.TokenValidationParameters.ValidAudiences = new[] { "api://your-client-id", Configuration["AzureActiveDirectory:ClientId"] }; });
2. 检查Angular端的Scope配置与权限授权
你的Angular代码中配置了api://WEBAPI-CLIENT-ID/api-access作为权限范围,需要确保:
- 在Azure门户的Web API应用注册中,「公开API」菜单下已创建
api-access这个范围 - 在Angular的应用注册中,「API权限」菜单下已添加Web API的
api-access权限,并且已完成管理员同意(针对租户内应用)
另外,确认protectedResourceMap中的API地址前缀和你实际请求的地址完全匹配,比如API路径是https://localhost:5000/api/values,映射应该写成:
export const protectedResourceMap:[string, string[]][]=[ ['https://localhost:5000/api/', ['api://WEB-API-CLIENTID/api-access']] ];
避免因路径不匹配导致MsalInterceptor没有自动附加令牌。
3. 完善API端的令牌验证参数
对于ASP.NET Core 3.1的Azure AD v2.0认证,你可以补充配置更多验证规则,确保令牌的发行者(Issuer)也符合预期:
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options => { options.Authority += "/v2.0"; options.TokenValidationParameters.ValidAudience = Configuration["AzureActiveDirectory:ClientId"]; options.TokenValidationParameters.ValidateIssuer = true; options.TokenValidationParameters.ValidIssuer = $"https://login.microsoftonline.com/{Configuration["AzureActiveDirectory:TenantId"]}/v2.0"; });
4. 验证中间件顺序与配置细节
你的Configure方法中中间件顺序是正确的(UseRouting → UseAuthentication → UseAuthorization),但要确保appsettings.json中的TenantId、ClientId没有复制错误,尤其是连字符和大小写。
5. 用Postman做最小化测试
从浏览器localStorage中取出Angular获取到的访问令牌(通常存在msal.accesstoken字段),在Postman中手动添加请求头:
Authorization: Bearer <你的访问令牌>
发送请求到API。如果仍然返回401,可以在appsettings.json中开启认证日志调试:
"Logging": { "LogLevel": { "Microsoft.AspNetCore.Authentication": "Debug" } }
查看详细日志,定位具体是哪个验证环节失败(比如受众不匹配、签名无效、发行者不正确等)。
内容的提问来源于stack exchange,提问作者Joker Bench

