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

.NET Core 2.2 API对接Azure AD认证时遇CORS错误求助

解决Azure AD多租户OIDC认证下的CORS重定向问题

看起来你遇到的核心问题不是普通的CORS配置错误,而是AJAX请求遇到302重定向到跨域登录页时被浏览器拦截的问题。让我一步步帮你拆解和解决:

问题本质

当未认证的前端AJAX请求访问带[Authorize]的API时,ASP.NET Core默认会返回302重定向到Azure AD登录页。但浏览器的CORS机制会拦截这个重定向的响应——因为重定向目标(login.microsoftonline.com)的响应没有包含你的前端域名的Access-Control-Allow-Origin头,所以浏览器直接阻止了这个跳转。

手动能打开登录页是因为直接导航不属于AJAX请求,不受CORS限制,但AJAX请求的重定向就会触发这个问题。


第一步:纠正前端请求的错误配置

你当前的fetch请求里加了错误的请求头:Access-Control-Allow-Origin和Access-Control-Allow-Headers是服务器返回给前端的响应头,前端请求时不需要设置这些,反而会触发不必要的OPTIONS预请求,甚至导致CORS校验失败。修改前端代码:

fetch('api/SampleData/WeatherForecasts', {
  method: "get",
  credentials: 'include' // 必须带上这个,因为Azure AD认证是基于Cookie的
})

第二步:让API返回401而非302重定向

对于AJAX请求,我们不需要返回302重定向,而是返回401未授权状态码,让前端自己处理登录跳转。在Startup.cs的ConfigureServices里修改Cookie认证的事件:

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
    .AddAzureAD(options => Configuration.Bind("AzureAd", options))
    .AddCookie(options =>
    {
        options.Events = new CookieAuthenticationEvents
        {
            OnRedirectToLogin = context =>
            {
                // 判断当前请求是否是API/AJAX请求
                bool isApiRequest = context.Request.Path.StartsWithSegments("/api") 
                    || context.Request.Headers["X-Requested-With"] == "XMLHttpRequest";

                if (isApiRequest)
                {
                    // 对于API请求,返回401而非重定向
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    return Task.CompletedTask;
                }

                // 非API请求(比如页面导航),正常重定向到登录页
                context.Response.Redirect(context.RedirectUri);
                return Task.CompletedTask;
            }
        };
    });

第三步:前端处理401状态并跳转登录

当下端返回401时,前端手动跳转到登录页(ASP.NET Core的OIDC中间件已经帮你准备好了登录路径/signin-oidc):

fetch('api/SampleData/WeatherForecasts', {
  method: "get",
  credentials: 'include'
})
.then(response => {
  if (response.status === 401) {
    // 跳转到Azure AD登录页
    window.location.href = '/signin-oidc';
  } else {
    return response.json();
  }
})
.catch(error => console.error('请求出错:', error));

第四步:确保CORS配置正确

你的CORS配置位置基本正确,但要注意:

  1. UseCors必须放在UseAuthentication之后,UseMvc之前,这样认证后的请求才能经过CORS校验。
  2. 因为我们用了credentials: 'include',所以CORS策略必须包含.AllowCredentials()——你当前的配置已经加了这个,没问题。
  3. 生产环境不要用AllowAnyOrigin(),要指定你的前端域名(比如https://yourapp.azurewebsites.net),避免安全风险。

另外,控制器上的[EnableCors]如果没有指定策略名,会使用默认策略,你可以在ConfigureServices里注册一个默认策略:

services.AddCors(setup =>
{
    setup.AddDefaultPolicy(policy =>
    {
        policy
        .AllowCredentials()
        .AllowAnyHeader()
        .AllowAnyMethod()
        .WithOrigins("https://localhost:44363"); // 生产环境替换成你的实际域名
    });
});

额外检查点

  • 确认Azure AD应用注册的重定向URI已经添加了https://localhost:44363/signin-oidc(从你的服务器日志看已经配置了,但再确认一遍)。
  • 多租户场景下ValidateIssuer = false的配置是正确的,因为不同租户的Issuer会不一样。

这样修改后,前端就不会再遇到CORS拦截的问题,而是在未登录时主动跳转到Azure AD登录页,登录完成后再正常调用API。

内容的提问来源于stack exchange,提问作者Ivan Nifantyef

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:43