基于 Multi-tenant Asp.net Core 网站中参数的 JWT 认证

Posted

技术标签:

【中文标题】基于 Multi-tenant Asp.net Core 网站中参数的 JWT 认证【英文标题】:JWT authentication based on the Parameter in Multi-tenant Asp.net Core web site 【发布时间】:2019-12-19 02:09:38 【问题描述】:

我在我的 .net core 2.1 网站中使用基于 JWT 的身份验证。目前这工作正常。现在,我必须创建一个 API 多租户,并且每个租户都有自己的密钥。租户 ID 将作为参数传递给 API。

        [Authorize]
        [HttpGet("tenant/id")]
        public async Task<IActionResult> GetInfo(string id)
        
        

每个租户都将签署 JWT 并将添加到 Authorization 标头。我想不出根据参数更改 IssuerSigningKey 的方法。我尝试了以下操作:

    通过将 JWT 设为 [AllowAonymus] 来验证 API 中的 JWT。这可行,但我最终编写了所有 JWT 验证代码。

    实现ISecurityTokenValidator

我可以实现ISecurityTokenValidator 来验证令牌并在启动配置中使用它,如下所示:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            
                options.SecurityTokenValidators.Clear();
                options.SecurityTokenValidators.Add(new JWTSecurityTokenValidator());
            );

并实现了我自己的类来验证令牌。

public class JWTSecurityTokenValidator : ISecurityTokenValidator

    public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    
            // Implement the logic
    

但我最终还是做了繁重的工作。另外,我无法访问 ValidateToken 中的参数“tenantId”。

3.使用IssuerSigningKeyResolver: 我可以实现一个委托:

IEnumerable<SecurityKey> IssuerSigningKeyResolver(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)

同样,我无法访问“tenantId”参数来选择合适的密钥。

是否有优雅的解决方案可以根据参数选择IssuerSigningKey,这样我就不需要编写自己的逻辑来验证 JWT?还是唯一的选择是选择第一个选项?

【问题讨论】:

【参考方案1】:

您可以使用 DI 将 IHttpContextAccessor 实例传递给您的 JWTSecurityTokenValidator 并获取 IHttpContextAccessor.HttpContext 属性的值。

从 .Net Core 2.1 开始,您可以使用扩展名注册:

services.AddHttpContextAccessor();

然后在您的自定义 JWTSecurityTokenValidator 中,修改以注入 IHttpContextAccessor

private readonly IHttpContextAccessor _httpContextAccessor;

public JWTSecurityTokenValidator(IHttpContextAccessor httpContextAccessor) 
    _httpContextAccessor = httpContextAccessor;

修改Startup.cs中的注册:

options.SecurityTokenValidators.Clear();

options.SecurityTokenValidators.Add(new JWTSecurityTokenValidator(services.BuildServiceProvider().GetService<IHttpContextAccessor>()));

这样在ValidateToken方法中,你可以从_httpContextAccessor.HttpContext读取参数,根据你传递参数的方式,从查询字符串或路径中读取:

public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)

        var xx = _httpContextAccessor.HttpContext.Request;
        ........

【讨论】:

以上是关于基于 Multi-tenant Asp.net Core 网站中参数的 JWT 认证的主要内容,如果未能解决你的问题,请参考以下文章

SMTP 服务器无法从托管 c#asp.net 发送电子邮件

ASP.Net MVC 3 中基于数据的权利/授权

asp.net是啥?

ASP.NET Razor (标记)语言概要

ASP.NET Core 中的 Jwt 令牌身份验证

ASP.NET是啥