.NET 6 API缺失Access-Control-Allow-Origin头及认证问题排查
解决.NET 6 Azure AD Web API跨域与认证问题
一、修复跨域(CORS)与HTTPS重定向冲突
你的307错误核心是中间件顺序错误:UseHttpsRedirection在CORS之前执行时,重定向响应不会携带CORS头,导致前端跨域校验失败。正确的中间件顺序必须保证CORS最先处理请求,后续的重定向、认证操作才能继承CORS头。
正确的Program.cs配置
var builder = WebApplication.CreateBuilder(args); // 1. 配置CORS策略,允许前端源携带凭证 builder.Services.AddCors(options => { options.AddPolicy("AllowReactFrontend", policy => { policy.WithOrigins("http://localhost:3001") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // 必须开启,因为请求携带Authorization令牌 }); }); // 2. 添加Azure AD认证服务 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); // 3. 配置授权规则 builder.Services.AddAuthorization(); builder.Services.AddControllers(); var app = builder.Build(); // 中间件顺序严格遵循:CORS → HTTPS重定向 → 认证 → 授权 → 路由 app.UseCors("AllowReactFrontend"); app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
二、解决401未授权(Scope为空)问题
日志显示"Scope为空",说明令牌缺少API要求的权限范围,或API未配置Scope校验。
1. 确认Azure AD权限配置
- 登录Azure门户,找到你的API应用注册,在公开API中确认已定义有效Scope(例如
api://{API客户端ID}/access_as_user)。 - 找到前端的Web应用注册,在API权限中添加上述Scope,并完成管理员同意(测试环境可手动同意,生产环境需管理员操作)。
2. 在API中强制校验Scope
在Program.cs的认证配置中添加Scope验证逻辑:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(options => { builder.Configuration.Bind("AzureAd", options); // 验证令牌中的Scope是否包含API要求的权限 options.Events = new JwtBearerEvents { OnTokenValidated = context => { var scopes = context.Principal.FindFirst("scp")?.Value; if (string.IsNullOrEmpty(scopes) || !scopes.Contains("access_as_user")) { context.Fail("令牌缺少API所需权限范围"); } return Task.CompletedTask; } }; }, options => builder.Configuration.Bind("AzureAd", options));
也可以通过授权策略统一管控:
builder.Services.AddAuthorization(options => { options.AddPolicy("ApiAccessPolicy", policy => { policy.RequireAuthenticatedUser(); policy.RequireClaim("scp", "access_as_user"); // 替换为你的API Scope }); });
然后在控制器/Action上添加[Authorize(Policy = "ApiAccessPolicy")]注解。
3. 前端令牌获取校验
确保前端用MSAL.js等库获取令牌时,指定API的完整Scope:
// MSAL.js示例:获取API专用令牌 const tokenRequest = { scopes: ["api://{你的API客户端ID}/access_as_user"] }; const tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest); // 请求API时携带:Authorization: Bearer ${tokenResponse.accessToken}
三、额外检查项
- 确认
launchSettings.json中API的applicationUrl为HTTPS地址(例如https://localhost:5220),前端直接请求HTTPS地址可避免重定向触发的额外问题。 - 检查浏览器开发者工具的网络面板:确认请求头包含
Origin: http://localhost:3001和正确的Authorization头,响应头包含Access-Control-Allow-Origin: http://localhost:3001。
内容的提问来源于stack exchange,提问作者cs.kali
相关产品推荐
相关产品推荐

