So, I'm trying to implement an OIDC client application using ASP.NET Core 3.1. I am trying to leverage the .AddOpenIdConnect() and .AddJswtBearer() middleware. However, I need some clarification on what this middleware is doing.
Here is what I currently have for the middleware configuration:
.AddOpenIdConnect(options =>
{
options.Authority = Configuration["auth:oidc:authority"];
options.ClientId = Configuration["auth:oidc:clientid"];
options.ClientSecret = Configuration["auth:oidc:clientsecret"];
options.ResponseType = OpenIdConnectResponseType.Code;
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
})
.AddJwtBearer(options =>
{
options.Authority = Configuration["auth:oidc:authority"];
options.Audience = Configuration["auth:oidc:clientid"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = Configuration["auth:oidc:authority"],
ValidAudience = Configuration["auth:oidc:clientid"],
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero
};
}
I notice that requests to the Authorization server's /.well-known/oidc-configuration and /.well-known/keys endpoints are requested when the application is first started, based on my Fiddler capture below

Where does it do that?
I'm trying to also validate that the JWT received from the authorization server is valid (that it hasn't been tampered with between the time the server sent it, and the time that the client has received it). I understood this to happen when I added the TokenValidationParameters object in the .AddJwtBearer() middleware. To test this, I tried changing Valid Audience in the TokenValidationParameters to something like asdkwewrj which I know is not the valid audience for my token. But, I never got an error from the client saying that the audience was invalid. The authentication still worked, and I was able to access my secure dashboard still.
Another thing I'm trying to implement is refresh_token grant_type with this OIDC client. I thought that the options.saveTokens in the .AddOpenIdConnect() middleware would allow me to save the tokens. It looks like they're save as cookies, but these cookies look nothing like my token values (my access token is a JWT, but out of the cookies I see, none of them begin with ey).
In a nutshell, I'm trying to understand the following:
.AddJwtBearer() middleware validate the ID Token for me if I have the correct JwtBearerOptions defined (like I do above)? Or do I need to manually validate the ID token against the JWKs from the JWKs URI?/.well-known/keys endpoint?Thank you! I am still fairly new to in-depth ASP.NET development like this, so I appreciate any responses.
First of all, the OIDC authentication scheme and the JWT bearer authentication scheme are independent of each other. OIDC is mostly used for server-side authentication and will pretty much never be used on its own but always with the cookie scheme. The reason for this is that the OIDC scheme will just be used for the authentication but is not able to persist the information on its own. I’ve went into more details in a different answer of mine that also explains how the authentication flow works with OIDC.
As for JWT bearer, this authentication scheme will run on every request since it is completely stateless and expects clients to authenticate themselves using the Authorization header all the time. This makes it primarily used for protecting APIs since browsers wouldn’t be able to provide a JWT for normal browser requests.
So you should first ask yourself whether you are protecting your server-side web application (e.g. using Razor views or Razor pages) in which case you want to use OIDC and the cookies authentication scheme, or if you are protecting your API. Of course, the answer could be “both” in which case you want all of those three schemes but ASP.NET Core will not support this without further configuration.
With that being clarified, let’s get into your questions:
The requests to /.well-known/oidc-configuration and /.well-known/keys are done by both the OIDC and the JWT bearer scheme in order to retrieve information from your identity provider. They will do that regularly to update their data, including information about the signining keys which they will use to validate the tokens. This happens within the scheme handler and is usually not visible to you.
Correctly set up, the JWT bearer authentication will validate the token for you. It will do that by verifying the signatures using the retrieved signing keys, and then it may check additional properties like the specified audience or its lifetime.
You shouldn’t ever need to validate tokens manually. That’s the job of the authentication scheme. You are using the authentication stack so you can just access the user principal within your app without doing anything.
Cookies are protected using data protection so that they are safe against forgery. In order to retrieve the tokens stored with SaveTokens = true, you can use the GetTokenAsync method on your HTTP context.
You can use the authentication events to add to the default behavior of the authentication schemes. For validating your tokens using the standard mechanisms, you shouldn’t need to though.
There is just one middleware: The authentication middleware. It uses the configured authentication schemes to perform the authentication of users so that—once set up correctly—the authenticated user is available throughout the application, e.g. in controllers, MVC filters, Razor views, etc.
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