.NET Core 3.1 Web API添加UseAuthentication后CORS策略失效问题
问题原因及解决办法
核心原因
在IIS部署环境下,中间件顺序错误或预检OPTIONS请求被Azure AD认证拦截,导致CORS响应头无法正常返回:
- 若
UseCors在UseAuthentication之后,预检OPTIONS请求会先被认证中间件拦截(OPTIONS请求不带Azure AD Token),直接返回401,CORS中间件根本没机会添加响应头。 - IIS自带的CORS模块可能和ASP.NET Core的CORS配置冲突,覆盖或阻止了自定义CORS头的输出。
解决步骤
1. 调整中间件顺序(关键)
在Startup.cs的Configure方法中,必须将UseCors放在UseAuthentication和UseAuthorization之前,确保所有请求(包括预检OPTIONS)先经过CORS处理:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); // 先启用CORS,再处理认证 app.UseCors("Allow"); // 认证和授权中间件放在CORS之后 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
2. 允许OPTIONS请求匿名访问
预检OPTIONS请求不会携带Azure AD Token,需要让这类请求跳过认证检查,避免被拦截。可选择以下两种方式:
方式一:全局配置跳过OPTIONS认证
在ConfigureServices中添加策略:
services.AddAuthorization(options => { options.AddPolicy("AllowAnonymousOptions", policy => { policy.RequireAssertion(context => { return context.Request.Method == HttpMethod.Options.Method; }); }); });
然后在路由上应用该策略:
app.UseEndpoints(endpoints => { endpoints.MapControllers().RequireAuthorization("AllowAnonymousOptions"); });
方式二:自定义中间件直接放行OPTIONS请求
在Configure方法的UseCors之前添加:
app.Use(async (context, next) => { if (context.Request.Method == HttpMethod.Options.Method) { context.Response.Headers.Add("Access-Control-Allow-Origin", "https://example.com"); context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization"); context.Response.StatusCode = 200; return; } await next(); });
3. 禁用IIS自带的CORS模块
若服务器安装了IIS的CORS模块,它会优先于ASP.NET Core的CORS配置生效:
- 打开IIS管理器,找到目标API站点
- 进入CORS功能,点击右侧的禁用
- 重启站点,确保ASP.NET Core的CORS配置完全生效
4. 验证CORS策略配置
确认ConfigureServices中的策略正确包含客户端Origin:
services.AddCors(options => { options.AddPolicy("Allow", builder => { builder.WithOrigins("https://example.com") // 替换为客户端实际域名 .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); // 客户端带凭证时需添加 }); });
验证方法
部署后用浏览器开发者工具查看请求响应头:
- 正常情况下,OPTIONS预检请求和实际请求都会返回
Access-Control-Allow-Origin: https://example.com - 若仍无该头,检查IIS的HTTP响应头设置,是否存在冲突的手动配置
内容的提问来源于stack exchange,提问作者Pascal Stephan
相关产品推荐
相关产品推荐

