I'm developing a multi-tenant SPA application that calls a back-end .Net Core Web API for data. The front end UI will use MSAL and Microsoft's v2 common endpoint for authenticating the user against AAD and obtaining an id and access token.
In my Web API, I want to validate the issuer, but as noted here, using the common endpoint provides metadata that makes the normal issuer validation un-useable.
I've seen references to a couple places where it may be possible to override or customize token validation, but I'm not sure which is preferred or if either of these methods causes undesired side effects.
One method uses the Events of the JwtBearer options: options.Events.TokenValidated
and the other uses the IssuerValidator
delegate of the TokenValidationParameters.
I don't want to have to write any token validation logic other than just ensuring the issuer exists in my database of verified issuers. Should that logic go in the IssuerValidator
or TokenValidated
?
My current code looks like this (currently set up for single tenant)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://myauthority.com";
options.Audience = "https://myaudience.com/api/v1";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "myauthority.com",
ValidateAudience = true,
ValidAudience = "https://myaudience.com",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
};
});
One of the issues I see with using IssuerValidator
is that there does not appear to be a way to inject or pass in a reference to a dbContext needed to be able to look up a tenant id in a database.
Has anyone tackled this or done something similar?
You can check that in OnTokenValidated
event , to access the database context , you can try :
options.Events.OnTokenValidated = async (context) =>
{
var dbContext = context.HttpContext.RequestServices.GetRequiredService<BloggingContext>();
var blogs = await dbContext.Blogs.ToListAsync();
if (!true)
{
throw new SecurityTokenValidationException($"Tenant xxxxx is not registered");
}
};