同域React+ASP.NET Core应用Azure AD认证后端401问题求助
解决Azure AD单应用注册下React+ASP.NET Core的401验证问题
核心问题分析
你遇到的401问题,本质是前端获取的令牌不满足后端的验证要求——单应用注册模式是可行的,但需要正确配置API范围、令牌请求参数和后端验证规则。
步骤1:修正前端令牌请求的Scopes
当前代码中scopes: [{clientId}]是错误的,Azure AD要求请求应用暴露的API范围,而非直接使用ClientId。
先在Microsoft Entra管理中心配置API范围:
- 打开你的应用注册,进入「公开API」页面
- 点击「添加范围」,设置:
- 范围名称:
access_as_user(自定义名称,比如代表用户访问后端API) - 同意类型:选择「管理员和用户同意」
- 填写说明后保存,最终范围格式为
api://{clientId}/access_as_user
- 范围名称:
修改前端令牌请求代码:
// Try to acquire token silently const tokenResult = await this.msalInstance.acquireTokenSilent({ account: this.account, scopes: ["api://{clientId}/access_as_user"], // 替换为你刚创建的API范围 }); return tokenResult.accessToken;
步骤2:调整后端验证配置
修改appsettings.json的AzureAd配置:
关键是将Audience设置为应用的API标识符(而非ClientId):
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "{tenantId}", "ClientId": "{clientId}", "Audience": "api://{clientId}" // 改为API标识符 }
优化后端Program.cs的认证配置:
确保验证规则匹配令牌的Issuer和Audience,可显式配置TokenValidationParameters:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(options => { builder.Configuration.Bind("AzureAd", options); // 明确指定有效受众 options.TokenValidationParameters.ValidAudience = "api://{clientId}"; // 验证V2版本的Issuer options.TokenValidationParameters.IssuerValidator = (issuer, token, parameters) => { var validIssuer = $"https://login.microsoftonline.com/{builder.Configuration["AzureAd:TenantId"]}/v2.0"; if (issuer == validIssuer) return issuer; throw new SecurityTokenInvalidIssuerException("无效的Issuer"); }; }, options => builder.Configuration.Bind("AzureAd", options)); // 确保中间件顺序正确:先认证,再授权,最后路由 app.UseAuthentication(); app.UseAuthorization(); app.MapControllers();
步骤3:验证API授权
在你的ASP.NET Core API控制器上添加[Authorize]属性,确保只有携带有效令牌的请求能访问:
[ApiController] [Route("api/[controller]")] [Authorize] public class YourController : ControllerBase { // 你的API方法 }
常见排查点
- 令牌内容检查:用jwt.ms解析前端获取的令牌,确认
aud(受众)是api://{clientId},scp(范围)包含你配置的access_as_user - 权限同意:在Entra管理中心的「API权限」页面,确保已为应用授予你创建的API范围(管理员需手动同意)
- 前端请求头:确保请求后端时,将令牌放在
Authorization头中,格式为Bearer {token}
内容的提问来源于stack exchange,提问作者Marcel Hoekstra
相关产品推荐
相关产品推荐

