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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:27:03