ASP.NET Core 3.0+Angular 8集成Windows Auth时POST预检请求401问题
解决ASP.NET Core 3.0 + Angular 8 Windows认证下POST请求401的问题
我之前做内部系统时碰到过完全一样的场景——Windows认证下GET请求正常,POST却返回401,关掉认证就一切正常。核心原因是POST请求会触发OPTIONS预检请求,而Windows认证默认会拦截不带凭证的OPTIONS请求,导致预检失败,浏览器直接拦截后续的POST请求返回401。下面是几个亲测有效的解决方案:
1. 调整ASP.NET Core中间件顺序(关键第一步)
你的Startup.cs里中间件顺序有误,ASP.NET Core 3.x及以后版本中,UseCors必须放在UseRouting之后、UseAuthentication之前,否则CORS策略无法正确应用到路由请求(包括预检的OPTIONS请求)。修改后的Configure方法如下:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); // 调整UseCors到正确位置:UseRouting之后,UseAuthentication之前 app.UseCors("FrontEndPolicy"); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
2. 让OPTIONS请求跳过Windows认证
OPTIONS预检请求不会携带Windows凭证,所以需要让服务器允许这类请求匿名访问,有两种实现方式:
方式A:添加全局中间件直接处理OPTIONS
在Configure方法最顶部(甚至在UseHttpsRedirection之前)添加一个中间件,直接给OPTIONS请求返回200状态码:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 优先处理OPTIONS请求,直接返回200 app.Use(async (context, next) => { if (context.Request.Method == HttpMethod.Options.Method) { context.Response.StatusCode = StatusCodes.Status200OK; await context.Response.CompleteAsync(); return; } await next(); }); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseCors("FrontEndPolicy"); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
方式B:通过IIS配置允许OPTIONS匿名(IIS托管场景)
如果你的API部署在IIS上,可以直接在web.config中添加规则,让IIS跳过OPTIONS请求的认证:
<configuration> <system.webServer> <security> <authorization> <add accessType="Allow" users="*" verbs="OPTIONS"/> </authorization> </security> </system.webServer> </configuration>
3. 验证CORS响应头
修改完成后,用浏览器开发者工具查看OPTIONS请求的响应头,确认包含以下关键字段:
Access-Control-Allow-Origin: http://localhost:4200Access-Control-Allow-Credentials: trueAccess-Control-Allow-Headers: content-type(因为你的POST请求带了JSON Body,会触发这个头的预检)
只要这些头正确返回,Angular的POST请求就能正常携带Windows凭证访问API了。
内容的提问来源于stack exchange,提问作者Necrophallus
相关产品推荐
相关产品推荐

