一尘不染

使用多个JWT承载身份验证

c#

是否可以在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
                };
        }

我可以有多个发行人和受众,但不能设置多个授权机构。


阅读 754

收藏
2020-05-19

共1个答案

一尘不染

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

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允许您覆盖哪些身份验证方案有效的属性。

如果您有更复杂的方案,则可以使用基于策略的授权。我发现官方文档很棒。

假设某些操作仅适用于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")]某些操作。

2020-05-19