如何使用JwtSecurityTokenHandler和JWKS端点验证JWT?

Ste*_*idi 8 asp.net oauth-2.0 jwt openid-connect identityserver4

我正在使用IdentityServer4来保护多个服务的原型,但需要注意的是,这些服务可能无法迁移(在可预见的未来)以使用ASP.NET Core的OWIN中间件习惯用法.因此,我不能利用许多中间件助手来自动验证JWT,只需提供IdentityServer的着名JWKS端点等等.

如果我可以重建这种行为会很好,我想尽可能利用微软的JwtSecurityTokenHandler实现.但是,我无法弄清楚如何利用IdentityServer的发现端点提供的类型JsonWebKeySetJsonWebKey类型来提取密钥并执行验证.

JwtSecurityTokenHandler用于TokenValidationParameters验证JWT,这些参数需要一个或多个SecurityKey对象的实例来执行验证.

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);
}
Run Code Online (Sandbox Code Playgroud)

如何从执行必要的转换JsonWebKeySet,以IEnumerable<SecurityKey>使可能发生的验证?是否有其他方法(除了OWIN中间件)也可以使用DiscoveryResponse上面的数据?

(遗憾的是,文档System.IdentityModel.Tokens.Jwt不是最新的.)

Dan*_*iel 10

var jwks = "{ keys: [..." // your jwks json string
var signingKeys = new JsonWebKeySet(jwks).GetSigningKeys();
Run Code Online (Sandbox Code Playgroud)

然后只需将其分配给IssuerSigningKeys您的TokenValidationParameters.

如果您从 Web 服务读取 jwks,那么您首先需要一个 http 客户端来读取它。


lea*_*ege 9

检查此示例:

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

它从JWK手动检索密钥并填充验证参数.

  • 太棒了 - 谢谢!我忽略了样本,并在导航中间件实现的源代码时迷失了:) (2认同)