Angular POST对接ASP.NET Core Web API遇CORS及401问题求助
解决POST/PUT请求CORS预检失败问题(Windows AD身份验证场景)
核心原因
启用Windows身份验证且关闭匿名访问后,浏览器自动发送的OPTIONS预检请求会被要求身份验证,但浏览器不会自动携带Windows凭据到OPTIONS请求,导致预检请求被拒绝,无法返回CORS响应头,最终POST/PUT请求失败。
具体解决步骤
1. 允许OPTIONS请求匿名访问
在ASP.NET Core中,需要单独对OPTIONS请求开放匿名权限,让预检请求能正常通过并返回CORS头。
.NET 6+ 最小API配置(Program.cs)
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); builder.Services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; }); // 配置CORS策略 builder.Services.AddCors(options => { options.AddPolicy("AllowAngular", policy => { policy.WithOrigins("http://localhost:4200") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); var app = builder.Build(); // 在认证前添加中间件,处理OPTIONS请求 app.Use(async (context, next) => { if (context.Request.Method == HttpMethod.Options.Method) { context.Response.StatusCode = StatusCodes.Status200OK; await context.Response.WriteAsync(string.Empty); return; } await next(); }); app.UseCors("AllowAngular"); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
.NET 5及以前配置(Startup.cs)
在Configure方法中,UseAuthentication之前添加:
app.Use(async (context, next) => { if (context.Request.Method == "OPTIONS") { context.Response.StatusCode = 200; await context.Response.WriteAsync(string.Empty); return; } await next(); });
同时确保UseCors中间件在UseAuthentication和UseAuthorization之前执行。
2. 确认CORS策略正确性
检查你的CORS策略是否包含以下配置:
- 指定了正确的前端源:
http://localhost:4200 - 启用了
AllowCredentials()(匹配客户端的withCredentials: true) - 允许POST/PUT等方法(或直接用
AllowAnyMethod())
3. IIS部署额外配置(如果部署到IIS)
- 在IIS站点的身份验证模块中,同时启用Windows身份验证和匿名身份验证(代码已处理OPTIONS匿名,不会影响其他请求的身份验证逻辑)
- 在IIS的CORS模块中,配置对应源并允许凭据
4. Angular客户端验证
确保请求正确设置withCredentials:
import { HttpClient } from '@angular/common/http'; constructor(private http: HttpClient) {} submitData(data: any) { return this.http.post('https://localhost:44314/api/CompletionDate', data, { withCredentials: true }); }
验证方法
修改配置后重启后端服务,打开浏览器开发者工具的网络面板:
- 确认OPTIONS请求状态码为200
- 检查响应头是否包含
Access-Control-Allow-Origin: http://localhost:4200和Access-Control-Allow-Credentials: true
此时再测试POST/PUT请求,即可正常运行。
内容的提问来源于stack exchange,提问作者Ruth
相关产品推荐
相关产品推荐

