gpt4 book ai didi

asp.net-core - 如何在 dotnet core 中验证非对称签名的 JWT?

转载 作者:行者123 更新时间:2023-12-03 13:20:09 24 4
gpt4 key购买 nike

我找到了 .NET FW 中的非对称签名示例和 .NET Core 中的对称签名示例,但我无法弄清楚如何在 .NET Core 中非对称地验证 JWT。给定 JWK 集的 URL 或给定公钥,如何在 .NET Core 中验证 token ?

最佳答案

A Symmetric Signing 和 Symmetric Signing 之间的唯一区别是签名 key 。只需为 token 验证参数构造一个新的非对称安全 key 即可。

假设您想使用 RSA 算法。让我们使用 powershell 导出一对 RSA key ,如下所示:

$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider -ArgumentList 2048

$rsa.ToXmlString($true) | Out-File key.private.xml
$rsa.ToXmlString($false) | Out-File key.public.xml

现在我们将使用这两个 key 对 token 进行签名。

一点修补

由于 rsa.FromXmlString() api受.NET Core支持,我只是复制 @myloveCc's code构建 RsaParameters在 C# 中(这项工作通过以下 ParseXmlString() 方法完成):

public static class KeyHelper 
{
public static RSAParameters ParseXmlString( string xml){
RSAParameters parameters = new RSAParameters();

System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(xml);

if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue"))
{
foreach (System.Xml.XmlNode node in xmlDoc.DocumentElement.ChildNodes)
{
switch (node.Name)
{
case "Modulus": parameters.Modulus = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "Exponent": parameters.Exponent = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "P": parameters.P = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "Q": parameters.Q = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "DP": parameters.DP = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "DQ": parameters.DQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "InverseQ": parameters.InverseQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "D": parameters.D = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
}
}
}
else
{
throw new Exception("Invalid XML RSA key.");
}
return parameters;
}


public static RsaSecurityKey BuildRsaSigningKey(string xml){
var parameters = ParseXmlString(xml);
var rsaProvider = new RSACryptoServiceProvider(2048);
rsaProvider.ImportParameters(parameters);
var key = new RsaSecurityKey(rsaProvider);
return key;
}
}

这里我添加一个 BuildRsaSigningKey()生成 SecurityKey 的辅助方法.

代币生成

这是一个使用 RSA 生成 token 的演示:


public string GenerateToken(DateTime expiry)
{
var tokenHandler = new JwtSecurityTokenHandler();
var Identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "..."),
// ... other claims
});

var xml = "<RSAKeyValue> load...from..local...files...</RSAKeyValue>";
SecurityKey key = KeyHelper.BuildRsaSigningKey(xml);

var Token = new JwtSecurityToken
(
issuer: "test",
audience: "test-app",
claims: Identity.Claims,
notBefore: DateTime.UtcNow,
expires: expiry,
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest)
);
var TokenString = tokenHandler.WriteToken(Token);
return TokenString;
}

token 验证

要自动验证它,请配置 JWT Bearer 身份验证,如下所示:

Services.AddAuthentication(A =>
{
A.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
A.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(O =>
{
var xml = "<RSAKeyValue> load...from..local...files...</RSAKeyValue>";
var key = KeyHelper.BuildRsaSigningKey(xml);

O.RequireHttpsMetadata = false;
O.SaveToken = true;
O.IncludeErrorDetails = true;
O.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = key,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
// ... other settings
};
});

如果您想手动验证它:

public IActionResult ValidateTokenManually(string jwt)
{
var xml = "<RSAKeyValue>... the keys ...</RSAKeyValue>";
SecurityKey key = KeyHelper.BuildRsaSigningKey(xml);

var validationParameters = new TokenValidationParameters
{
IssuerSigningKey = key,
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true,
// ... other settings
};

var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(jwt, validationParameters, out var rawValidatedToken);
var securityToken = (JwtSecurityToken)rawValidatedToken;
return Ok(principal);
}

关于asp.net-core - 如何在 dotnet core 中验证非对称签名的 JWT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56696254/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com