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

Angular调用.NET Core后端API遇Azure AD CORS预检跨域认证问题

问题排查与解决方案

核心结论

Azure AD不是导致CORS预检错误的原因——你能正常调用Graph API,说明Azure AD颁发的Token有效,认证流程无问题。CORS预检错误完全是后端(.NET Core)或请求配置的问题,与Azure AD无关;Angular端无需配置CORS,CORS是后端服务必须处理的跨域规则。

重点排查预检(OPTIONS请求)环节

浏览器发送预检请求(OPTIONS)是为了确认后端允许跨域调用,后端必须正确响应该请求并返回Access-Control-Allow-Origin等必要头。以下是常见问题及解决办法:

1. .NET Core中间件顺序错误

确保UseCors的位置绝对正确,必须在UseAuthentication、UseAuthorization之前,且在UseRouting之后。错误的顺序会导致CORS头无法被添加到响应中:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他基础中间件(如异常处理、HTTPS重定向)
    app.UseHttpsRedirection();
    
    app.UseRouting();
    
    // 关键:UseCors必须在UseAuthentication/UseAuthorization之前
    app.UseCors("YourCorsPolicy");
    
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

2. 认证中间件拦截OPTIONS请求

OPTIONS预检请求不会携带Authorization头,若后端认证中间件(OIDC)强制校验所有请求,会直接返回401,导致CORS头无法返回。需配置允许OPTIONS请求匿名访问:

  • 方案一:在全局配置中忽略OPTIONS的认证校验
// 在ConfigureServices中添加
services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    // 允许OPTIONS请求匿名
    options.AddPolicy("AllowOptions", policy =>
    {
        policy.RequireAssertion(context => 
            context.Request.Method == HttpMethod.Options.Method);
    });
});

// 在Configure的Endpoints中应用
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers()
        .RequireAuthorization()
        .WithMetadata(new AuthorizeAttribute { Policy = "AllowOptions" });
});
  • 方案二:单独处理OPTIONS请求,直接返回CORS头
app.UseEndpoints(endpoints =>
{
    // 优先处理所有OPTIONS请求
    endpoints.MapOptions("{*path}", context =>
    {
        var origin = context.Request.Headers["Origin"].FirstOrDefault();
        if (!string.IsNullOrEmpty(origin))
        {
            context.Response.Headers.Add("Access-Control-Allow-Origin", origin);
        }
        context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
        context.Response.Headers.Add("Access-Control-Allow-Methods", "*");
        return Task.CompletedTask;
    });
    
    endpoints.MapControllers();
});

3. Azure App Service CORS设置覆盖代码配置

如果后端部署在Azure App Service,Portal中的CORS设置会覆盖代码里的CORS配置。请检查:

  • 登录Azure Portal -> 你的App Service -> 左侧菜单「CORS」
  • 确保Allowed Origins包含你的Angular应用域名,或选择「允许所有来源」(测试用,生产环境建议指定域名)
  • 若已在代码中配置CORS,建议关闭Portal的CORS设置,避免冲突

4. CORS策略未正确包含必要头

前端请求携带Authorization头(Bearer Token),属于非简单请求,后端CORS策略必须明确允许该头:

services.AddCors(options =>
{
    options.AddPolicy("AllowAngularApp", builder =>
    {
        builder.WithOrigins("https://your-angular-app-domain") // 生产环境指定具体域名
               .AllowAnyMethod()
               .AllowHeaders("Authorization", "Content-Type") // 明确允许认证头和内容类型头
               .AllowCredentials(); // 若前端带Cookie需开启,SSO场景一般无需,但建议保留
    });
});

Angular端注意事项

Angular本身无需配置CORS,但需确保MSAL拦截器正确将Token添加到请求头:

  • 确认MsalInterceptor已注册到app.module.ts:
import { MsalInterceptor, MsalModule } from '@azure/msal-angular';

@NgModule({
    imports: [
        MsalModule.forRoot({ /* 你的MSAL配置 */ })
    ],
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: MsalInterceptor,
            multi: true
        }
    ]
})
export class AppModule { }
  • 检查请求是否携带Authorization: Bearer <token>头,可通过浏览器开发者工具的「网络」标签查看。

内容的提问来源于stack exchange,提问作者Taher Tarek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:45:35