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

ASP.NET Core API(v2.1)多认证方案仅默认Schema生效问题排查

解决ASP.NET Core 2.1多JWT认证仅默认Scheme生效的问题

看起来你遇到的是多JWT认证场景下的常见误区——默认的认证与授权逻辑并不会自动支持「任意一个Scheme通过即可」的需求,这里有两个关键配置被你忽略了,咱们一步步来解决:

问题根源拆解

1. 授权策略默认是「AND」逻辑

你当前的授权策略代码:

options.DefaultPolicy = new AuthorizationPolicyBuilder()
    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme, OtherSchema)
    .RequireAuthenticatedUser()
    .Build();

这段代码的实际含义是:用户必须同时通过两个Scheme的认证才能访问接口,而不是通过其中一个就行。这也是为什么只有默认Scheme的令牌能通过——另一个Scheme的认证根本没触发,自然满足不了「双Scheme都通过」的要求。

2. 认证中间件只会使用默认Scheme验证令牌

你在AddAuthentication中指定了默认Scheme为JwtBearerDefaults.AuthenticationScheme,所以认证中间件只会用这个Scheme的配置去解析令牌,完全不会尝试MyOtherSchema的验证规则。哪怕交换AddJwtBearer的顺序,默认Scheme还是第一个,结果当然不会改变。


完整解决方案

我们需要同时调整认证和授权配置,让系统能根据令牌特征选择对应Scheme验证,并且授权时允许任意一个Scheme通过:

1. 配置PolicyScheme作为默认认证入口,动态选择验证Scheme

把默认认证Scheme替换为自定义的PolicyScheme,让它根据令牌的Issuer(或其他Claims)动态选择对应的JWT验证规则:

public void ConfigureServices(IServiceCollection services)
{
    const string OtherSchema = "MyOtherSchema";
    const string MultiJwtScheme = "MultiJwtScheme"; // 自定义PolicyScheme名称

    services.AddAuthentication(MultiJwtScheme)
        // 添加PolicyScheme作为默认认证入口
        .AddPolicyScheme(MultiJwtScheme, "Multiple JWT Authentication", options =>
        {
            options.ForwardDefaultSelector = context =>
            {
                // 从请求头提取Bearer令牌
                var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
                if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))
                {
                    return JwtBearerDefaults.AuthenticationScheme;
                }

                var token = authHeader.Substring(7);
                var jwtHandler = new JwtSecurityTokenHandler();
                
                if (jwtHandler.CanReadToken(token))
                {
                    var jwtToken = jwtHandler.ReadJwtToken(token);
                    // 根据令牌的Issuer选择对应的验证Scheme
                    // 替换为你两个JWT的实际Issuer地址
                    if (jwtToken.Issuer == "https://your-first-issuer.com")
                    {
                        return JwtBearerDefaults.AuthenticationScheme;
                    }
                    else if (jwtToken.Issuer == "https://your-second-issuer.com")
                    {
                        return OtherSchema;
                    }
                }

                // 默认返回第一个Scheme
                return JwtBearerDefaults.AuthenticationScheme;
            };
        })
        // 第一个JWT Scheme配置
        .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
        {
            options.TokenValidationParameters = GetFirstTokenValidationParameters();
        })
        // 第二个JWT Scheme配置
        .AddJwtBearer(OtherSchema, options =>
        {
            options.TokenValidationParameters = GetSecondTokenValidationParameters();
        });

2. 修改授权策略为「OR」逻辑,允许任意一个Scheme通过

调整授权规则,只要用户通过任意一个指定Scheme的认证即可访问接口:

services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .RequireAssertion(context =>
            // 检查用户是否持有任意一个Scheme的认证身份
            context.User.Identities.Any(identity =>
                identity.AuthenticationType == JwtBearerDefaults.AuthenticationScheme ||
                identity.AuthenticationType == OtherSchema))
        .Build();
});

额外说明

  • 如果你的两个JWT没有Issuer区分(比如Issuer相同但Audience不同),也可以根据Audience或其他自定义Claims来判断选择哪个Scheme。
  • 若不想做动态判断,也可以自定义认证Handler让系统依次尝试所有Scheme,但动态选择的方式性能更优。

这样配置后,不管是默认Scheme的令牌还是MyOtherSchema的令牌,都会被对应的规则正确验证,并且只要通过其中一个就能完成授权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:25:56