我正在使用IdentityServer4来保护多个服务的原型,但需要注意的是,这些服务可能无法迁移(在可预见的未来),以使用ASP.NET Core的OWIN中间件习惯用法。因此,我不能利用许多中间件助手来自动验证JWT,只需提供着名的IdentityServer JWKS端点等等。
如果我能重建这种行为会很好,我想尽可能利用微软的JwtSecurityTokenHandler
实现。但是,我无法弄清楚如何利用IdentityServer的发现端点提供的JsonWebKeySet
和JsonWebKey
类型来提取密钥并执行验证。
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);
}
如何执行从JsonWebKeySet
到IEnumerable<SecurityKey>
的必要转换,以便进行验证?是否有其他方法(除了OWIN中间件)也能使用上面的DiscoveryResponse
数据?
(可悲的是,System.IdentityModel.Tokens.Jwt
的文档不是最新的。)
答案 0 :(得分:9)
检查此样本:
它从JWK手动检索密钥并填充验证参数。
答案 1 :(得分:0)
var jwks = "{ keys: [..." // your jwks json string
var signingKeys = new JsonWebKeySet(jwks).GetSigningKeys();
然后只需将其分配给IssuerSigningKeys
的{{1}}属性即可。
如果您正在从Web服务读取jwks,则需要一个http客户端才能首先读取它。