我正在开发一个以 asp.net 核心3.1作为后端的多租户应用程序。我使用 JWT 对用户进行身份验证。我正在传递租户 ID 和 http 请求,我想根据租户 ID 验证 JWT。为此,我必须在每个客户端请求时将tenantId传递给JwtBearerOptions.ValidAudience。
我在启动时设置选项如下...
public void ConfigureServices(IServiceCollection services){
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = jwtOptions["Issuer"];
configureOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = jwtOptions["Issuer"],
ValidAudience = tenantId,
ValidateIssuerSigningKey = true,
IssuerSigningKey = accessKey,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
}
请注意,我不想将所有 tenantId 传递给 ValidateAudiences,因为每个租户都应该收到一个唯一的令牌。 例如,我不希望租户 X 的令牌适用于租户 Y。
我如何实现这一点?
提前感谢!
我不确定为什么要将租户 ID 设置为Audience
,但您可以使用自定义受众验证器来实现TokenValidationParameters
中的逻辑:
AudienceValidator = (audiences, securityToken, validationParameters) =>
{
//return true/false based on your requirement
return true;
},
我最终使用下面来验证 tenderid,我对结果非常满意。 如果下面有缺点,请告诉我,谢谢!
ValidAudiences = tenants.Value.Select(x=>x.TenantId).ToList(),
IssuerSigningKeyResolver = (string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters) =>
{
var tenant = tenants.Value.Where(t => t.TenantId == kid).FirstOrDefault();
List<SecurityKey> keys = new List<SecurityKey>();
if (tenant != null && kid == tenantsResolver.GetCurrentTenantId())
{
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tenant.SecretKey));
keys.Add(signingKey);
}
return keys;
}