基于Multi-tenantAsp.net核心网站参数的JWT认证
JWT authentication based on the Parameter in Multi-tenant Asp.net Core web site
我在我的 .net core 2.1 网站中使用基于 JWT 的身份验证。目前这工作正常。现在,我必须制作一个 API multi-tenant 并且每个租户都将拥有自己的密钥。租户 ID 将作为参数传递给 API.
[Authorize]
[HttpGet("tenant/{id}")]
public async Task<IActionResult> GetInfo(string id)
{
}
每个租户将签署 JWT 并将添加到授权 header。我想不出一种方法来根据参数更改 IssuerSigningKey。我试过以下:
通过使 [AllowAonymus
] 验证 API 中的 JWT。这可行,但我最终编写了所有 JWT 验证代码。
实施ISecurityTokenValidator
我可以实现 ISecurityTokenValidator
来验证令牌并在启动配置中使用它,如下所示:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new JWTSecurityTokenValidator());
});
并实现了我自己的 class 来验证令牌。
public class JWTSecurityTokenValidator : ISecurityTokenValidator
{
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
// Implement the logic
}
}
但我又一次完成了繁重的工作。另外,我无法访问 ValidateToken 中的参数 "tenantId"。
3.UsingIssuerSigningKeyResolver
:
我可以实现一个委托:
IEnumerable<SecurityKey> IssuerSigningKeyResolver(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
同样,我无法访问 "tenantId" 参数来选择合适的密钥。
是否有优雅的解决方案根据参数选择IssuerSigningKey
,这样我就不需要自己编写逻辑来验证JWT?或者唯一的选择是选择第一个选项?
您可以使用 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;
........
}
我在我的 .net core 2.1 网站中使用基于 JWT 的身份验证。目前这工作正常。现在,我必须制作一个 API multi-tenant 并且每个租户都将拥有自己的密钥。租户 ID 将作为参数传递给 API.
[Authorize]
[HttpGet("tenant/{id}")]
public async Task<IActionResult> GetInfo(string id)
{
}
每个租户将签署 JWT 并将添加到授权 header。我想不出一种方法来根据参数更改 IssuerSigningKey。我试过以下:
通过使 [
AllowAonymus
] 验证 API 中的 JWT。这可行,但我最终编写了所有 JWT 验证代码。实施
ISecurityTokenValidator
我可以实现 ISecurityTokenValidator
来验证令牌并在启动配置中使用它,如下所示:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new JWTSecurityTokenValidator());
});
并实现了我自己的 class 来验证令牌。
public class JWTSecurityTokenValidator : ISecurityTokenValidator
{
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
// Implement the logic
}
}
但我又一次完成了繁重的工作。另外,我无法访问 ValidateToken 中的参数 "tenantId"。
3.UsingIssuerSigningKeyResolver
:
我可以实现一个委托:
IEnumerable<SecurityKey> IssuerSigningKeyResolver(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
同样,我无法访问 "tenantId" 参数来选择合适的密钥。
是否有优雅的解决方案根据参数选择IssuerSigningKey
,这样我就不需要自己编写逻辑来验证JWT?或者唯一的选择是选择第一个选项?
您可以使用 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;
........
}