基于多租户Asp.net Core网站中参数的JWT身份验证
我正在.net core 2.1网站中使用基于JWT的身份验证.目前,这可以正常工作.现在,我必须使一个API多租户,每个租户将拥有它自己的密钥.租户ID将作为参数传递给API.
I am using JWT based authentication in my .net core 2.1 web site. Currently this works fine. Now, I have to make one API multi-tenant and each tenant will have it's own secret key. The tenant Id will be passed as parameter to the API.
[Authorize]
[HttpGet("tenant/{id}")]
public async Task<IActionResult> GetInfo(string id)
{
}
每个租户都将签署JWT,并将其添加到Authorization标头中.我无法考虑一种基于参数更改IssuerSigningKey的方法.我尝试了以下操作:
Each tenant will sign the JWT and will add to Authorization header. I am not able to think of a way to change IssuerSigningKey based on the parameter. I tried following:
-
通过使其成为[
AllowAonymus
]来验证API中的JWT.这行得通,但我最终编写了所有的JWT验证代码.
Validating the JWT inside the API by making it [
AllowAonymus
]. This works but I have end up writing all the JWT validating code.
实施ISecurityTokenValidator
我可以实现ISecurityTokenValidator
来验证令牌,并在启动配置中使用它,如下所示:
I can implement ISecurityTokenValidator
to validate the token and using this in startup configuration something like this:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new JWTSecurityTokenValidator());
});
并实现了我自己的类来验证令牌.
And implemented my own class to validate the token.
public class JWTSecurityTokenValidator : ISecurityTokenValidator
{
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
// Implement the logic
}
}
但是我最终还是举起了沉重的负担.另外,我无法访问ValidateToken中的参数"tenantId".
But again I end up doing heavy lifting. Also, I am not able to access the parameter "tenantId" in the ValidateToken.
3.使用IssuerSigningKeyResolver
:
我可以实现一个委托:
3.Using IssuerSigningKeyResolver
:
I can implement a delegate:
IEnumerable<SecurityKey> IssuerSigningKeyResolver(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
同样,我无权访问"tenantId"参数来选择适当的密钥.
Again I don't's have access to the "tenantId" parameter to choose the appropriate key.
是否存在基于参数选择IssuerSigningKey
的优雅解决方案,因此我无需编写自己的逻辑即可验证JWT?还是唯一的选择就是第一个选择?
Is there elegant solution to choosing IssuerSigningKey
based on the parameter so that I don't need to write my own logic to validate JWT? Or only option is to go with first option?
您可以使用DI将IHttpContextAccessor
实例传递到您的JWTSecurityTokenValidator
中,并获取IHttpContextAccessor.HttpContext
属性的值.
You can use DI to pass IHttpContextAccessor
instance into your JWTSecurityTokenValidator
and get value of IHttpContextAccessor.HttpContext
property.
在.Net Core 2.1中,您可以使用扩展名注册:
From .Net Core 2.1 , you can register using extension :
services.AddHttpContextAccessor();
然后在您的自定义JWTSecurityTokenValidator
中,进行修改以注入IHttpContextAccessor
:
Then in your custom JWTSecurityTokenValidator
, modify to inject the 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
中读取参数,从查询字符串或路径中读取该参数:
So that in ValidateToken
method ,you can read the parameter from _httpContextAccessor.HttpContext
, according to how you pass the parameter , read it from query string or path :
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
var xx = _httpContextAccessor.HttpContext.Request;
........
}