c# - 使用 Microsoft 的 IdentityModel 验证 JWT

标签 c# jwt json-web-token

我正在尝试验证以下测试 JWT,所选 key 是“私有(private)”,我可以在 https://jwt.io 上成功验证它

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIyNzFjNmFkYjNhYTk1YTIxZWI3ZTljMTE2OGViNjI2YiIsImlhdCI6MTQ5MDE5NzQ2MCwibmJmIjoxNDkwMTk3NDYwLCJleHAiOjE0OTAyMDEwNjAsIklwIjoiNzkuMjMxLjczLjE1NCIsIk1lbWJlcklkIjoxfQ.P3m7RkXJ9TUiUFJ2bbtiyoL7OXaD7ITq_LsWMCRJj04

Microsoft 似乎已经更改了 JwtSecurityTokenhandler() 类并且文档并不是真正最新的。我检查了一些使用 new InMemorySymetricSecurityKey() 的教程和 gitpages,但这个类甚至不再存在。

Nuget 包: Install-Package System.IdentityModel.Tokens.Jwt(版本 5.1.3)。

我创建了一个简单的控制台应用程序并尝试验证给定的 JWT,但我不知道应该如何指定 TokenValidationParameters。

static void Main(string[] args)
{
    var key = "private";
    var jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIyNzFjNmFkYjNhYTk1YTIxZWI3ZTljMTE2OGViNjI2YiIsImlhdCI6MTQ5MDE5NzQ2MCwibmJmIjoxNDkwMTk3NDYwLCJleHAiOjE0OTAyMDEwNjAsIklwIjoiNzkuMjMxLjczLjE1NCIsIk1lbWJlcklkIjoxfQ.P3m7RkXJ9TUiUFJ2bbtiyoL7OXaD7ITq_LsWMCRJj04";

    var tokenHandler = new JwtSecurityTokenHandler();
    var securityToken = tokenHandler.ReadToken(jwt);
    var validationParameters = new TokenValidationParameters {IssuerSigningKey = new InMemorySymetricSecurityKey()};
    SecurityToken validated;
    tokenHandler.ValidateToken(jwt, validationParameters, out validated);

    Console.WriteLine(validated.ToString());
}

最佳答案

[查看下面的更新]

这取决于谁签署了 JWT token 。通常,颁发 token 的授权服务器使用其签名凭证的公钥发布元数据。

您的代码可以下载元数据并使用公钥验证 token 。例如 Azure AD 发布其签名 key here .

您可以使用此代码来验证 Azure AD 颁发的 JWT token 。

var jwtToken = "<JWT TOKEN>";
var url = "https://login.windows.net/common/federationmetadata/2007-06/federationmetadata.xml";
var serializer = new MetadataSerializer();
MetadataBase metadata = serializer.ReadMetadata(XmlReader.Create(url));

var entityDescriptor = (EntityDescriptor)metadata;
var securityTokens = new List<X509SecurityToken>();
var descriptor = entityDescriptor.RoleDescriptors.OfType<SecurityTokenServiceDescriptor>().First();

var x509DataClauses = descriptor.Keys.Where(key => key.KeyInfo != null &&
                                           (key.Use == KeyType.Signing || key.Use == KeyType.Unspecified))
                                     .Select(key => key.KeyInfo.OfType<X509RawDataKeyIdentifierClause>().First());

securityTokens.AddRange(x509DataClauses.Select(token => new X509SecurityToken(new X509Certificate2(token.GetX509RawData()))));

var validationParameters = new TokenValidationParameters
{
    IssuerSigningTokens = securityTokens,
    CertificateValidator = X509CertificateValidator.ChainTrust,
};
SecurityToken validatedToken;
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwtToken, validationParameters, out validatedToken);

更新: 我误读了您的问题并错过了您指定的对称 key 的字面值。您应该能够像这样使用 SymmetricSecurityKey:

HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(key));

var validationParameters = new TokenValidationParameters
{
    IssuerSigningKey = new SymmetricSecurityKey(hmac.Key);
};

关于c# - 使用 Microsoft 的 IdentityModel 验证 JWT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42964432/

相关文章:

c# - 重试命令/连接超时是否安全?

c# - 使用 Ninject 绑定(bind)到常量和绑定(bind)到作用域中的类型

WCF DataContract 的 C# 类结构

c#:如何在页面重定向到另一个页面之前在客户端中显示成功消息

c# - 在 ASP.NET Core 3 中使用 id_token

node.js - 如何从路由调用jwt验证功能?

go - 迁移到centos后编译golang时出错

javascript - 使用 JsonWebToken 授权 header 获取图像

node.js - 使用 JWT 撤销/使 token 无效

javascript - jsonwebtoken.sign() 失败并设置了 expiresIn 选项