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

时间:2016-11-16 02:56:39

标签: 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);
}

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

(可悲的是,System.IdentityModel.Tokens.Jwt的文档不是最新的。)

2 个答案:

答案 0 :(得分:9)

答案 1 :(得分:0)

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

然后只需将其分配给IssuerSigningKeys的{​​{1}}属性即可。

如果您正在从Web服务读取jwks,则需要一个http客户端才能首先读取它。