如何动态设置 JwtBearerOptions?
How to set JwtBearerOptions dynamically?
我正在开发一个以 asp.net 核心 3.1 作为后端的多租户应用程序。我使用 JWT 来验证用户。我将 tenantId 与 http 请求一起传递,我想根据 tenantIds 验证 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
};
});
}
请注意,我不想将所有租户 ID 都传递给 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;
}
我正在开发一个以 asp.net 核心 3.1 作为后端的多租户应用程序。我使用 JWT 来验证用户。我将 tenantId 与 http 请求一起传递,我想根据 tenantIds 验证 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
};
});
}
请注意,我不想将所有租户 ID 都传递给 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;
}