使用多个 JWT 承载认证 [英] Use multiple JWT Bearer Authentication

查看:42
本文介绍了使用多个 JWT 承载认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to support multiple JWT Token issuers in ASP.NET Core 2? I want to provide an API for external service and I need to use two sources of JWT tokens - Firebase and custom JWT token issuers. In ASP.NET core I can set the JWT authentication for Bearer auth scheme, but only for one Authority:

  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
                };
        }

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

I can have multiple issuers and audiences, but I can't set several Authorities.

推荐答案

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

You can totally achieve what you want:

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();
    });

让我们来看看你的代码和那个代码之间的区别.

Let's go through the differences between your code and that one.

如果您设置了默认身份验证方案,那么在每次请求时,身份验证中间件都会尝试运行与默认身份验证方案关联的身份验证处理程序.由于我们现在有两个可操作的身份验证方案,因此运行其中一个没有意义.

If you set a default authentication scheme, then on every single request the authentication middleware will try to run the authentication handler associated with the default authentication scheme. Since we now have two opssible authentication schemes, there's no point in running one of them.

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

Every single AddXXX method to add an authentication has several overloads:

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

Now, because you use the same authentication method twice but authentication schemes must be unique, you need to use the second overload.

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

Since the requests won't be authenticated automatically anymore, putting [Authorize] attributes on some actions will result in the requests being rejected and an HTTP 401 will be issued.

因为这不是我们想要的,因为我们想让身份验证处理程序有机会对请求进行身份验证,所以我们通过同时指示 FirebaseCustom 来更改授权系统的默认策略 验证方案应该尝试来验证请求.

Since that's not what we want because we want to give the authentication handlers a chance to authenticate the request, we change the default policy of the authorization system by indicating both the Firebase and Custom authentication schemes should be tried to authenticate the request.

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

That doesn't prevent you from being more restrictive on some actions; the [Authorize] attribute has an AuthenticationSchemes property that allows you to override which authentication schemes are valid.

如果你有更复杂的场景,你可以使用基于策略的授权.我发现官方文档很棒.

If you have more complex scenarios, you can make use of policy-based authorization. I find the official documentation is great.

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

Let's imagine some actions are only available to JWT tokens issued by Firebase and must have a claim with a specific value; you could do it this way:

// 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")].

You could then use [Authorize(Policy = "FirebaseAdministrators")] on some actions.

最后一点要注意:如果您正在捕获 AuthenticationFailed 事件并使用除第一个 AddJwtBearer 策略之外的任何内容,您可能会看到 IDX10501:签名验证失败.Unable to match key... 这是由系统依次检查每个AddJwtBearer 直到匹配为止造成的.该错误通常可以忽略.

A final point to note: If you are catching AuthenticationFailed events and using anything but the first AddJwtBearer policy, you may see IDX10501: Signature validation failed. Unable to match key... This is caused by the system checking each AddJwtBearer in turn until it gets a match. The error can usually be ignored.

这篇关于使用多个 JWT 承载认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆