Steve Guidi Steve Guidi - 16 days ago 8
ASP.NET (C#) Question

How do I validate a JWT using JwtSecurityTokenHandler and a JWKS endpoint?

I am prototyping the use IdentityServer4 to secure several services, with the caveat that those services will likely not be migrated (in the forseeable future) to use the OWIN middleware idiom of ASP.NET Core. Consequently, I can not leverage the many middleware helpers that automate the validation of a JWT by simply providing the well-known JWKS endpoint of IdentityServer, among other things.

It would be nice if I could reconstruct this behavior, and I'd like to leverage Microsoft's

implementation if possible. However, I can not figure out how to utilize the
JsonWebKeySet
and
JsonWebKey
types provided via IdentityServer's discovery endpoint to extract keys and perform the validation.

JwtSecurityTokenHandler
uses
TokenValidationParameters
to validate a JWT, and those parameters require an instance of one or more
SecurityKey
objects to perform the validation.

ClaimsPrincipal ValidateJwt(string token, IdentityModel.Client.DiscoveryResponse discovery)
{
JwtSecurityToken jwt = new JwtSecurityToken(token);

TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidateIssuer = true,
RequireSignedTokens = true,
ValidIssuer = "expected-issuer",
ValidAudience = "expected-audience",
IssuerSigningKeys = discovery.KeySet.Keys /* not quite */
};

JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
SecurityToken validatedToken;
return handler.ValidateToken(jwt, validationParameters, out validatedToken);
}


How do I perform the necessary translation from
JsonWebKeySet
to
IEnumerable<SecurityKey>
so that the validation can occur? Is there another method (apart from OWIN middleware) that will also work using the
DiscoveryResponse
data above?

(Sadly, the documentation for
System.IdentityModel.Tokens.Jwt
is not up to date.)

Answer

Check this sample:

https://github.com/IdentityServer/IdentityServer4.Samples/blob/dev/Clients/src/MvcManual/Controllers/HomeController.cs#L81

It manually retrieves the key from the JWK and populates the validation parameters.