.NET Core 5迁移:Microsoft Identity扩展并行配置OpenId与Bearer认证
配置失效的核心原因
两个认证能力无法并行的本质是重复调用AddAuthentication引发的全局配置重置:
- 每一次调用
services.AddAuthentication(...),都会重新初始化整个认证系统的默认Scheme配置,覆盖之前所有已经注册的方案的全局默认值 - 不管你把OpenId配置和Bearer配置的书写顺序如何,最后执行的那行
AddAuthentication代码会把全局默认认证Scheme切到自己对应的方案上,直接冲掉另一个方案的全局配置:- 先写OpenId、再写Bearer:全局默认Scheme被设为Bearer,最终只有API认证生效
- 先写Bearer、再写OpenId:全局默认Scheme被设为OpenId,最终只有终端用户登录流程生效
这不是Microsoft.Identity.Web扩展的功能限制,是调用方式完全不符合框架的设计逻辑。
可直接落地的并行配置方案
整个配置的核心原则是:不重复创建认证构建器实例,在同一个构建器上追加两类认证能力,再通过全局路由转发实现按需切换认证方案。
- 保留原有OpenId认证的注册逻辑,直接链式追加Bearer认证能力,不要单独再调用
AddAuthentication:services.AddMicrosoftIdentityWebAppAuthentication( configuration, aadB2CConfigName, OpenIdConnectDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme, true) // 直接追加WebApi Bearer配置,不触发全局默认Scheme重置 .AddMicrosoftIdentityWebApi( configureJwtBearerOptions: jwtOptions => { configuration.Bind("AzureAd", jwtOptions); jwtOptions.Authority = configuration["AzureAd:Authority"]; jwtOptions.TokenValidationParameters.NameClaimType = "name"; jwtOptions.TokenValidationParameters.RoleClaimType = "roles"; }, configureMicrosoftIdentityOptions: b2cOptions => { configuration.Bind(aadB2CConfigName, b2cOptions); }); - 追加全局路径匹配的认证方案转发逻辑,实现
/api路径自动切换Bearer校验,其余路径走OpenId登录流程:services.AddAuthentication(options => { // 明确保留原有OpenId流程的默认方案配置,避免被重置 options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; // 根据请求路径动态选择认证方案 options.ForwardDefaultSelector = context => { // /api 开头的请求走Bearer Token校验 if (context.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCulture)) { return JwtBearerDefaults.AuthenticationScheme; } // 其余请求走默认的Cookie + OpenId登录流程 return null; }; });
高频踩坑提醒
- 不要重复调用
services.AddAuthentication():每次调用都会重新初始化认证系统的全局配置,直接覆盖之前注册的OpenId默认Scheme,是配置失效的最常见原因 - 不要将路径转发逻辑写到
JwtBearerOptions内部:ForwardDefaultSelector是认证全局层的路由配置,写在Bearer的专属options配置里完全不生效,这也是之前配置失效的次要原因 - 原有的授权策略、Microsoft Identity UI的配置可以完全保留,无需做任何适配修改:
services.AddControllersWithViews() .AddMicrosoftIdentityUI(); services.AddAuthorization(options => { options.AddPolicy("Tst1AuthPolicy", policy => policy.RequireRole("Tst1AppRole")); options.AddPolicy("Tst2AuthPolicy", policy => policy.RequireRole("Tst2AppRole")); }); - 如果遇到Blazor Server场景下的登录状态回写异常,只需要确保全局默认的认证方案是Cookie即可,不需要额外调整Cookie的路径参数配置
内容的提问来源于stack exchange,提问作者GGleGrand
相关产品推荐
相关产品推荐

