Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set JwtBearerOptions dynamically?

I'm developing a multi-tenant application with asp.net core 3.1 as the backend. I used JWT to authenticate users. I'm passing the tenantId along with the http request and I would like to validate JWT against tenantIds. To do this, I must pass the tenantIds to JwtBearerOptions.ValidAudience at each client request.

I set options at startup as follows...

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
            };
        });
}

Please note that I don't want to pass all tenantIds to ValidateAudiences because each tenant should receive an unique token. e.g. I don't want tenant X's token works for tenant Y.

How do I achieve this?

Thanks in advance!

like image 423
ecasper Avatar asked Oct 25 '25 22:10

ecasper


2 Answers

I'm not sure why you want to set tenant id as Audience , but you can use custom audience validator to implement the logic in TokenValidationParameters :

AudienceValidator = (audiences, securityToken, validationParameters) =>
{
    //return true/false based on your requirement 
    return true;
},
like image 127
Nan Yu Avatar answered Oct 28 '25 02:10

Nan Yu


I ended up using below for validating tenderid and I'm quite happy with the outcome. please let me know if there are drawbacks to approch below, thanks!

                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;
                }
like image 28
ecasper Avatar answered Oct 28 '25 03:10

ecasper