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

ASP.NET Core Blazor多认证方案(OIDC+自定义Cookie)实现问题

解决Blazor Web App多Cookie认证方案优先认证问题

1. 正确配置多认证方案

在Program.cs中同时注册OIDC和自定义Cookie方案,不设置默认认证方案,后续通过授权策略指定优先级:

builder.Services.AddAuthentication()
    // 保留原OIDC方案配置
    .AddOpenIdConnect(options =>
    {
        // 原OIDC配置项(如Authority、ClientId等)
        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    // 添加自定义Cookie认证方案
    .AddCookie("my-cookie-scheme", options =>
    {
        options.Cookie.Name = "my-cookie"; // 指定自定义Cookie名称
        options.Events = new CookieAuthenticationEvents
        {
            // 可选:添加Cookie验证逻辑
            OnValidatePrincipal = context =>
            {
                // 自定义验证逻辑,比如检查Claims有效性
                return Task.CompletedTask;
            }
        };
    });

2. 调整授权策略支持多方案

修改授权配置,设置默认策略按指定顺序尝试认证方案:

builder.Services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        // 按优先级排序:先尝试自定义Cookie方案,再用OIDC关联的Cookie方案
        .AddAuthenticationSchemes("my-cookie-scheme", CookieAuthenticationDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build();
});

3. 自定义认证状态提供器(核心步骤)

Blazor默认的PersistingAuthenticationStateProvider只会使用默认认证方案获取身份,因此需要自定义实现,让它按顺序尝试多个方案:

创建自定义状态提供器类:

public class CustomPersistingAuthenticationStateProvider : PersistingAuthenticationStateProvider
{
    private readonly IAuthenticationService _authService;
    private readonly IEnumerable<string> _schemeOrder;

    public CustomPersistingAuthenticationStateProvider(
        IOptions<PersistingComponentStateOptions> options,
        IAuthenticationService authService,
        IEnumerable<string> schemeOrder)
        : base(options)
    {
        _authService = authService;
        _schemeOrder = schemeOrder;
    }

    protected override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        // 按顺序尝试每个认证方案
        foreach (var scheme in _schemeOrder)
        {
            var authResult = await _authService.AuthenticateAsync(scheme);
            if (authResult.Succeeded)
            {
                return new AuthenticationState(authResult.Principal);
            }
        }

        // 所有方案失败时返回匿名状态
        return await base.GetAuthenticationStateAsync();
    }
}

在Program.cs中注册该自定义提供器,传入优先级方案列表:

builder.Services.AddScoped<PersistingAuthenticationStateProvider, CustomPersistingAuthenticationStateProvider>(sp =>
{
    var options = sp.GetRequiredService<IOptions<PersistingComponentStateOptions>>();
    var authService = sp.GetRequiredService<IAuthenticationService>();
    // 指定认证方案优先级:自定义Cookie优先,OIDC Cookie次之
    var schemeOrder = new List<string> { "my-cookie-scheme", CookieAuthenticationDefaults.AuthenticationScheme };
    return new CustomPersistingAuthenticationStateProvider(options, authService, schemeOrder);
});

4. 确保中间件顺序正确

在Program.cs中,中间件必须按以下顺序配置:

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(Counter).Assembly);

验证效果

现在请求携带my-cookie时,系统会优先用my-cookie-scheme完成认证,principal.Identity?.IsAuthenticated会返回true;若该Cookie无效或不存在,再自动尝试OIDC关联的Cookie方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:27:13