How does AddJwtBearer get my public key?
I sat one day in my chair at home, looking at the code below and thought
“How in the **** does UseAuthentication() know the publickey for validating JWT’s?”
So I did what I always do, go to the source code (thank god for open source).
TLDR;
It is fetched through the standard url of OpenIdConfiguration {yourdomain}/.well-known/openid-configuration
fetched and validated through the JWTBearerHandler
source code Line 87 here
Where it begins
So basically.
When you initialize the JWT Configuration with .AddJwtBearer( c => { c.authority = {url here}});
.AddJwtBearer
creates an instance of JwtBearerOptions
(Source here) which is handled in a ConfigurationManager<T>
. The ConfigurationManager<T>
takes an IConfigurationRetriever<T>
in its constructor.
Source code here
When used with Jwt, it will use this OpenIdConfigurationRetriever
which is technically a property of the JwtBearerOptions
from before
The OpenIdConfigurationRetriever
contains this method
What happens in this method is that
- it checks whether the
Uri
(uri of authority) is empty. - Gets what is located at the the
JwksUri
part of theOpenIdConfiguration
url specified in this metadata class. - The keys are then added to the
SigningKeys
Collection.
Where is it handled?
When we get a token from a consumer, it is handled in this JwtBearerHandler
, in the HandleAuthenticateAsync
method here.
What happens here is that;
- The configuration is fetched if it hasn’t been before.
- Validation parameters are constructed.
- The
SigningKeys
from before are added as validation parameters as well. - The token is validated, based on the prior validation parameters.
But.. foreach validator? how many are used?
Good question.. The answer is 1.
Namely this one.
It is initialized in the JwtBearerOptions
class here. (It is the same Validator for OpenIdConnectOptions