Web API中Windows Authentication下的CORS错误排查
问题分析与解决方案
1. 未在Web API请求管道中启用CORS策略
你仅在ConfigureServices中定义了CORS策略,但并未在请求管道中启用它。在.NET 6+的Program.cs中,需要添加UseCors中间件,且注意顺序——必须放在UseRouting之后、UseAuthentication和UseAuthorization之前:
var app = webApplicationBuilder.Build(); // 其他中间件配置 app.UseRouting(); // 启用指定的CORS策略 app.UseCors("NTLMPolicy"); app.UseAuthentication(); app.UseAuthorization(); // 路由映射 app.MapControllers(); app.Run();
2. IIS Windows认证拦截OPTIONS预检请求
POST请求会触发浏览器发送OPTIONS预检请求,而IIS的Windows认证默认会要求该请求携带凭证,导致预检失败(OPTIONS请求本身不会携带Cookie/凭证)。需要修改Web API的web.config,允许匿名访问OPTIONS请求:
<configuration> <system.webServer> <security> <authentication> <windowsAuthentication enabled="true" /> <anonymousAuthentication enabled="true" /> </authentication> </security> <handlers> <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" /> </handlers> </system.webServer> </configuration>
同时在Web API的授权配置中,添加允许OPTIONS请求匿名访问的策略:
webApplicationBuilder.Services.AddAuthorization(options => { options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); // 允许OPTIONS请求匿名访问 options.AddPolicy("AllowAnonymousOptions", policy => { policy.RequireAssertion(context => context.Request.Method == HttpMethod.Options.Method); }); });
然后在控制器上应用该策略:
[Authorize] [AllowAnonymous(Policy = "AllowAnonymousOptions")] [ApiController] [Route("[controller]")] public class CartController : ControllerBase { // 你的接口实现 }
3. CORS策略配置存在冲突
你同时使用了WithOrigins("https://localhost:7117")和SetIsOriginAllowed((host) => true),这两个配置会产生冲突——SetIsOriginAllowed会覆盖WithOrigins的来源限制。建议二选一:
- 若要允许指定来源:
void ConfigureCors(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("NTLMPolicy", policyBuilder => { policyBuilder.WithOrigins("https://localhost:7117") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); }
- 若要允许所有来源(生产环境不推荐):
void ConfigureCors(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("NTLMPolicy", policyBuilder => { policyBuilder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); }
4. Blazor端请求简化优化
可以使用HttpClient.PostAsJsonAsync替代手动序列化,简化代码同时避免格式错误:
public async Task<bool> SaveCartItem(SaveCartItemRequest request) { var response = await _httpClient.PostAsJsonAsync("Cart/SaveCartItem", request); return response.IsSuccessStatusCode; }
内容的提问来源于stack exchange,提问作者Chatra
相关产品推荐
相关产品推荐

