.NET 6下Blazor Web应用与API同时配置Azure AD B2C认证方案
Blazor Server同时支持OIDC和JWT认证的配置方案
你遇到的配置冲突核心是多次调用AddAuthentication()会覆盖前一次的全局默认认证方案,导致系统无法区分Blazor Server页面用的OIDC Cookie认证和客户端用的JWT认证场景,触发401错误。以下是可直接落地的配置方案:
1. 调整认证服务注册逻辑
只调用一次AddAuthentication(),链式追加两种认证方案,避免覆盖配置:
var builder = WebApplication.CreateBuilder(args); var services = builder.Services; var configuration = builder.Configuration; // 全局默认认证方案设为OIDC,适配Blazor Server管理端页面 services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) // 注册Blazor Server用的WebApp认证 .AddMicrosoftIdentityWebApp(configuration, "AzureB2C") .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches(); // 追加注册客户端用的JWT认证,不修改全局默认方案 services.AddAuthentication() .AddMicrosoftIdentityWebApi( configuration, "AzureB2C", jwtBearerScheme: JwtBearerDefaults.AuthenticationScheme);
2. 为不同类型的端点显式指定认证方案
对客户端调用的Hub、API端点,单独指定使用JWT认证方案,避免使用默认的OIDC方案验证令牌。
2.1 业务代码层标注
// 客户端调用的Hub显式指定JWT认证 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public class ClientHub : Hub { // 业务逻辑实现 } // 客户端调用的API控制器同理 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Route("api/[controller]")] public class ClientApiController : ControllerBase { // 接口逻辑实现 }
2.2 端点映射层统一指定(更推荐,方便管理)
var app = builder.Build(); // 基础中间件配置,顺序不能乱 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // 认证中间件必须放在路由之后、授权之前 app.UseAuthentication(); app.UseAuthorization(); // Blazor Server默认Hub使用全局OIDC认证 app.MapBlazorHub(); // 客户端Hub显式要求JWT认证 app.MapHub<ClientHub>("/client-hub") .RequireAuthorization(new AuthorizeAttribute { AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme }); // 客户端API统一指定JWT认证 app.MapControllers() .RequireAuthorization(new AuthorizeAttribute { AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme }); app.MapFallbackToPage("/_Host"); app.Run();
额外适配注意点
因为SignalR连接时浏览器存在头信息传输限制,需要额外配置JWT中间件支持从Query参数读取令牌:
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options => { options.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/client-hub")) { context.Token = accessToken; } return Task.CompletedTask; } }; });
同时要检查appsettings.json中Azure AD B2C配置的Audience字段,必须和Blazor WASM客户端请求令牌时传入的API受众一致。
内容的提问来源于stack exchange,提问作者Cowman
相关产品推荐
相关产品推荐

