首页 文章

使用多个JWT承载认证

提问于
浏览
18

是否有可能在ASP.NET Core 2中支持多个JWT令牌发行者?我想为外部服务提供API,我需要使用两个JWT令牌源 - Firebase和自定义JWT令牌发行者 . 在ASP.NET核心中,我可以为Bearer身份验证方案设置JWT身份验证,但仅限于一个权限:

services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://securetoken.google.com/my-firebase-project"
            options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = "my-firebase-project"
                    ValidateAudience = true,
                    ValidAudience = "my-firebase-project"
                    ValidateLifetime = true
                };
        }

我可以有多个发行人和受众,但我不能设置多个权限 .

1 回答

  • 40

    你可以完全实现你想要的:

    services
        .AddAuthentication()
        .AddJwtBearer("Firebase", options =>
        {
            options.Authority = "https://securetoken.google.com/my-firebase-project"
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = "my-firebase-project"
                ValidateAudience = true,
                ValidAudience = "my-firebase-project"
                ValidateLifetime = true
            };
        })
        .AddJwtBearer("Custom", options =>
        {
            // Configuration for your custom
            // JWT tokens here
        });
    
    services
        .AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes("Firebase", "Custom")
                .Build();
        });
    

    让我们来看看你的代码与那个代码之间的差异 .

    AddAuthentication没有参数

    如果设置了默认身份验证方案,则在每个请求中,身份验证中间件将尝试运行与默认身份验证方案关联的身份验证处理程序 . 由于我们现在有两种可视认证方案,因此运行其中一种方案毫无意义 .

    使用AddJwtBearer的另一个重载

    每个添加身份验证的 AddXXX 方法都有几个重载:

    现在,因为您使用相同的身份验证方法两次但身份验证方案必须是唯一的,您需要使用第二个重载 .

    更新默认策略

    由于请求将不再自动进行身份验证,因此在某些操作上放置 [Authorize] 属性将导致请求被拒绝并且将发出 HTTP 401 .

    由于这不是我们想要的,因为我们希望为身份验证处理程序提供对请求进行身份验证的机会,因此我们通过指示应尝试验证请求的 FirebaseCustom 身份验证方案来更改授权系统的默认策略 .

    这并不妨碍您对某些行为采取更严格的限制措施; [Authorize] 属性具有AuthenticationSchemes属性,允许您覆盖哪些身份验证方案有效 .

    如果您有更复杂的场景,则可以使用policy-based authorization . 我发现官方文档很棒 .

    让我们假设某些操作仅适用于Firebase发布的JWT令牌,并且必须具有特定值的声明;你可以这样做:

    // Authentication code omitted for brevity
    
    services
        .AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes("Firebase", "Custom")
                .Build();
    
            options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes("Firebase")
                .RequireClaim("role", "admin")
                .Build());
        });
    

    然后,您可以在某些操作上使用 [Authorize(Policy = "FirebaseAdministrators")] .

相关问题