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

如何获取非默认Authentication Scheme对应的ClaimsPrincipal?

问题原因

ASP.NET Core的认证中间件默认只会自动验证你指定的默认认证方案(也就是代码里的scheme1)。用scheme2登录后,虽然对应的Cookie已经生成,但中间件不会主动去验证这个非默认方案,所以context.User里不会有该方案的身份信息。另外你的代码里还有个隐藏问题:UseAuthentication()中间件的注册顺序错了,它被放在了路由定义之后,导致认证流程可能无法在端点处理前正常执行。

修复步骤

第一步:修正中间件顺序

把app.UseAuthentication()移到所有路由映射(MapGet等)的前面,确保认证流程在端点处理前完成:

var app = builder.Build();

// 先注册认证中间件
app.UseAuthentication();

// 再定义路由
app.MapGet("/", (HttpContext context) =>
{
    var result = JsonSerializer.Serialize(context.User, new JsonSerializerOptions
    {
        ReferenceHandler = ReferenceHandler.IgnoreCycles,
        WriteIndented = true
    });

    return result;
});

// 其他路由定义...

app.Run();

第二步:配置多方案认证(二选一即可)

方案A:让中间件自动尝试验证所有Cookie方案

通过添加一个策略方案,让认证中间件根据请求中的Cookie自动选择要验证的方案,或者按顺序尝试所有方案。修改服务注册代码:

const string scheme1 = "cookie1";
const string scheme2 = "cookie2";
const string combinedScheme = "combined-cookies";

builder.Services.AddAuthentication(combinedScheme)
    // 添加策略方案,用于组合多个Cookie认证
    .AddPolicyScheme(combinedScheme, "Combined Cookies", options =>
    {
        // 根据请求中的Cookie选择要验证的方案
        options.ForwardDefaultSelector = context =>
        {
            // 如果存在scheme2的Cookie,优先验证scheme2;否则用默认的scheme1
            if (context.Request.Cookies.ContainsKey(scheme2))
            {
                return scheme2;
            }
            return scheme1;
        };
    })
    .AddCookie(scheme1, options => { options.Cookie.Name = scheme1; })
    .AddCookie(scheme2, options => { options.Cookie.Name = scheme2; });

这样不管用哪个方案登录,中间件都会自动验证对应的Cookie,context.User就能正确获取到身份信息。

方案B:在端点手动验证非默认方案

如果只需要在特定端点验证scheme2,可以在端点方法里手动调用认证方法并合并身份:

app.MapGet("/", async (HttpContext context) =>
{
    // 手动验证两个方案
    var scheme1Result = await context.AuthenticateAsync(scheme1);
    var scheme2Result = await context.AuthenticateAsync(scheme2);

    var principals = new List<ClaimsPrincipal>();
    if (scheme1Result.Succeeded) principals.Add(scheme1Result.Principal);
    if (scheme2Result.Succeeded) principals.Add(scheme2Result.Principal);

    // 合并多个身份到context.User
    context.User = new ClaimsPrincipal(principals);

    var result = JsonSerializer.Serialize(context.User, new JsonSerializerOptions
    {
        ReferenceHandler = ReferenceHandler.IgnoreCycles,
        WriteIndented = true
    });

    return result;
});
额外说明

如果某些路由需要强制使用特定的认证方案,可以给路由添加授权策略,指定需要的方案:

app.MapGet("/only-scheme2", (HttpContext context) =>
{
    return JsonSerializer.Serialize(context.User, new JsonSerializerOptions
    {
        ReferenceHandler = ReferenceHandler.IgnoreCycles,
        WriteIndented = true
    });
}).RequireAuthorization(options =>
{
    options.AddPolicy("OnlyScheme2", policy =>
    {
        policy.AuthenticationSchemes.Add(scheme2);
        policy.RequireAuthenticatedUser();
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:32:17