You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2:带[Authorize]的API Ajax调用预检请求失败

解决AJAX请求过期时Azure AD授权的CORS问题

这个问题的核心其实很好理解:你看到的CORS错误不是你的API返回的,而是微软的login.microsoftonline.com授权端点没有给你的前端域名返回Access-Control-Allow-Origin头。当用户的token过期后,ASP.NET Core的身份认证中间件会自动尝试重定向到授权页面,但AJAX请求的跨域特性会让浏览器先发送OPTIONS预请求,而微软的授权端点根本就没设计支持跨域AJAX调用,所以必然会报错。

你的CORS配置之所以没用,是因为它只作用于你自己的API,管不到微软的授权服务器。下面是具体的解决方案:

1. 让后端在AJAX请求过期时返回401,而非自动重定向

我们需要修改OpenIdConnect中间件的行为,当检测到是AJAX请求时,不再跳转到授权页面,而是返回401 Unauthorized状态码,让前端自己处理登录跳转(页面跳转而非AJAX调用,就不会有CORS问题了)。

在ConfigureServices中配置OpenIdConnect时添加事件处理:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    // 这里保留你原有的ClientId、Authority、CallbackPath等配置
    options.Events = new OpenIdConnectEvents
    {
        OnRedirectToIdentityProvider = context =>
        {
            // 通过X-Requested-With头判断是否为AJAX请求
            if (context.Request.Headers.ContainsKey("X-Requested-With"))
            {
                // 返回401状态码,终止重定向流程
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                context.HandleResponse();
            }
            return Task.CompletedTask;
        }
    };
});

2. 前端捕获401并主动跳转登录

在你的AJAX请求封装里,添加错误处理逻辑,当收到401状态码时,主动跳转到登录页面(比如后端的登录路由,或者直接跳转到微软授权地址):

// 示例:用axios的拦截器
axios.interceptors.response.use(
    response => response,
    error => {
        if (error.response.status === 401) {
            // 跳转到登录页面,这里可以用后端生成的登录地址,或者直接拼接
            window.location.href = "/Account/Login";
        }
        return Promise.reject(error);
    }
);

3. 确认CORS中间件的顺序(重要!)

虽然CORS不是解决这个问题的核心,但确保你的CORS中间件顺序正确,能避免其他潜在问题。在Configure方法中,UseCors必须放在UseRouting之后,UseAuthentication和UseAuthorization之前,UseEndpoints之前:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他中间件:比如UseStaticFiles、UseHttpsRedirection等

    app.UseRouting();

    // CORS中间件要在这里
    app.UseCors(builder => builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials()
    );

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

为什么ASP.NET Core 1.0没问题?

ASP.NET Core 1.0的身份认证中间件在处理AJAX请求时的默认行为不同,它不会自动触发到授权服务器的重定向,而是直接返回401,所以不会出现跨域调用授权端点的问题。新版本的中间件优化了身份认证流程,但也带来了这个AJAX场景下的问题。

内容的提问来源于stack exchange,提问作者Métoule

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:17:37