Please help me to understand the difference between JWT token validation from the ASP netcore application and the netcore Kestrel hosted application.
There are two applications that verifies token using the source code like below:
public static IServiceCollection AddJwtToken(this IServiceCollection services, OAuthConfig config)
{
services.AddMvc();
services.AddAuthorization();
Logger.DebugFormat("AddJwtBearer authority:{0} audience:{1}", config.GetAuthority(), config.Resource);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => new JwtBearerOptions
{
Authority = config.GetAuthority(),
Audience = config.Resource,
});
return services;
}
it is pretty simple and it works well if token is being validated from the asp net core 2.2 application
// in the asp.net core
var builder = WebHost.CreateDefaultBuilder(args);
builder
.UseStartup<Startup>()
.ConfigureKestrel(_ => _.ConfigureEndpoints())
.UseSerilog();
And there is another application (console) that starts the same rest service host using the UseKestrel
//in the console app
var builder = WebHost.CreateDefaultBuilder()
.UseNLog()
.UseKestrel(_ => _.ConfigureEndpoints())
.UseStartup<Startup>();
the only one significant difference is that there is UseKestrel
in the console via ConfigureKestrel
for asp.net core.
The same source code (and configuration) is used to get token from the Azure AD.
Please find it as the gist here.
It is configured to get token from the https://login.microsoftonline.com/{tenant}/v2.0
provider. The same token endpoint, clientid, secret and scope values are used for both cases.
The problem is that AddJwtBearer
validates the token in the asp.net core and does not in the console app.
the error is
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys:
kid: 'BB8CeFVqyaGrGNuehJIiL4dfjzw',
token: '{"typ":"JWT","alg":"RS256","kid":"BB8CeFVqyaGrGNuehJIiL4dfjzw"}.{"aud":"2c163c99-935b-4362-ae0d-657f589f5565","iss":"https://login.microsoftonline.com/{tenantidhere}/v2.0
Why asp.net core host validates the token (for the first AddJwtBearer
implementation) and console host fails?
Thank you
to solve this error I've to load keys from the openid provider as below:
Logger.DebugFormat("AddJwtBearer authority:{0} audience:{1}", config.GetAuthority(), config.Resource);
IList<string> validissuers = new List<string>()
{
config.GetAuthority(),
};
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{validissuers.Last()}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
var openidconfig = configManager.GetConfigurationAsync().Result;
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, _ =>
{
_.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidateAudience = true,
ValidAudience = config.Resource,
ValidateIssuer = true,
ValidIssuers = new[] { config.GetAuthority() },
ValidateIssuerSigningKey = true,
IssuerSigningKeys = openidconfig.SigningKeys,
RequireExpirationTime = true,
ValidateLifetime = true,
RequireSignedTokens = true,
};
_.RequireHttpsMetadata = false;
});
And it started to work for both cases. But what is the difference with the old AddJwtBearer
implementation and the new one (related to the keys validation)? Keys where downloaded and supplied using the IssuerSigningKeys = openidconfig.SigningKeys
but why it is not loaded automatically using the .well-known/openid-configuration
by the AddJwtBearer
middleware ?
In my case, the same error was because of inadvertent use of the token received from one environment (https://dev/identity) and validated in another environment (i.e. http://local/identity).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With