如何为.NET Core Web API配置Azure AD全局身份认证
要让你的.NET Core 3.0 Web API + Angular 9应用实现全局认证,确保所有请求(包括静态文件和SPA入口)都经过Azure AD验证,同时保留会话持久化无需重复登录,可以按以下步骤操作:
1. 配置全局授权回退策略
首先,在Startup.cs的ConfigureServices方法中设置全局授权策略,这样所有请求默认都要求已认证用户,除非显式标记[AllowAnonymous]。这会自动覆盖控制器上的[Authorize]特性,实现全局保护:
services.AddAuthorization(options => { // 设置回退策略:所有未指定授权规则的请求都需要认证 options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); });
这个策略会作用于所有控制器路由和静态文件请求,无需再给每个控制器添加[Authorize]特性。如果有个别接口需要开放访问,只需在对应的控制器/方法上添加[AllowAnonymous]即可。
2. 调整中间件管道顺序(关键!)
.NET Core中间件的执行顺序直接决定了认证逻辑是否会覆盖静态文件请求。你需要确保认证和授权中间件在静态文件、路由和SPA中间件之前执行,这样所有请求都会先经过认证检查。
在Startup.cs的Configure方法中按以下顺序排列中间件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); // 1. 启用身份认证(必须在授权之前) app.UseAuthentication(); // 2. 启用授权(必须在静态文件中间件之前) app.UseAuthorization(); // 3. 处理Angular编译后的静态文件(替换为你的自定义文件夹路径) // 如果你的Angular构建输出在自定义目录,比如"/angular-dist",可以配置StaticFileOptions app.UseStaticFiles(new StaticFileOptions { RequestPath = "/angular-dist" }); // 4. 路由中间件 app.UseRouting(); // 5. 映射API控制器端点 app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // 6. 处理SPA路由回退(确保Angular的前端路由能正常工作) app.UseSpa(spa => { spa.Options.SourcePath = "ClientApp"; // 你的Angular项目根路径 // 指定SPA默认页面的静态文件路径(对应上面的自定义文件夹) spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions { RequestPath = "/angular-dist" }; // 开发环境使用Angular CLI热重载 if (env.IsDevelopment()) { spa.UseAngularCliServer(npmScript: "start"); } }); }
为什么这个顺序重要?
UseAuthentication和UseAuthorization必须在UseStaticFiles之前:这样静态文件请求(比如index.html、JS/CSS资源)会先经过认证检查,未登录用户会被重定向到Azure AD登录页。UseSpa放在最后:确保SPA的路由回退逻辑在API和静态文件之后执行,避免拦截API请求。
3. 验证Azure AD会话持久化
你已经配置的Azure AD认证代码会自动使用Cookie持久化会话:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme) .AddAzureAD(options => Configuration.Bind("AzureAd", options));
只要用户完成一次登录,浏览器会保存认证Cookie,后续请求会自动携带Cookie,无需重复登录。确保你的Azure AD应用注册中的回调URL与appsettings.json里的CallbackPath一致(默认是/signin-oidc),否则登录回调会失败。
4. 可选:开放个别无需认证的资源
如果有个别静态资源(比如favicon.ico)不需要认证,可以通过中间件条件判断跳过授权:
// 在UseAuthentication之后,UseAuthorization之前添加 app.UseWhen(context => !context.Request.Path.StartsWithSegments("/favicon.ico"), appBuilder => { appBuilder.UseAuthorization(); });
或者在对应的API方法上添加[AllowAnonymous]特性,开放特定接口。
完成以上配置后,所有请求(包括访问Angular的index.html、API接口)都会触发Azure AD认证,已登录用户的会话会被自动保留,无需重复登录。
内容的提问来源于stack exchange,提问作者Sandeep Thomas

