c# - 在 RSA 类上使用语句会导致 401 / 对象被过早处理?
问题描述
我目前遇到了使用公钥解密 jwts 的问题。当我使用带有 using 声明的 RSA 类时(为了安全起见,我也尝试了较旧的语法),每次都会得到 401。删除 using 关键字可以解决问题,但我确信这是不好的做法,因为 RSA 是 IDisposable。关于如何以正确的方式进行这项工作的任何想法?
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
var publicKey = tokenSettings.PublicKey.ToByteArray();
// removing "using" makes it work
using var rsa = RSA.Create();
rsa.ImportSubjectPublicKeyInfo(publicKey, out _);
var key = new RsaSecurityKey(rsa);
opt.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = key,
ValidAudience = tokenSettings.TargetAud,
ValidIssuers = new[] { tokenSettings.Issuer },
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true,
ValidateAudience = true,
ValidateIssuer = true,
ClockSkew = TimeSpan.Zero,
};
});
我确实在这里找到了一个自我回答RSA Disposed Object Error - every other test,但没有省略“使用” IDisposable 对象的不正确使用?
我还要注意,这与缓存问题不同,后者返回 200 一次,然后返回 401。该代码当前每次都返回 401。
解决方案
如何在大括号中设置 using-clause,这样它就不会在下一条指令后被处理?
services.AddAuthentication(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
System.ReadOnlySpan<byte> publicKey = tokenSettings.PublicKey.ToByteArray();
// removing "using" makes it work
using (System.Security.Cryptography.RSA rsa = System.Security.Cryptography.RSA.Create())
{
rsa.ImportSubjectPublicKeyInfo(publicKey, out _);
Microsoft.IdentityModel.Tokens.RsaSecurityKey key = new Microsoft.IdentityModel.Tokens.RsaSecurityKey(rsa);
opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
IssuerSigningKey = key,
ValidAudience = "tokenSettings.TargetAud",
ValidIssuers = new[] { "tokenSettings.Issuer" },
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true,
ValidateAudience = true,
ValidateIssuer = true,
ClockSkew = System.TimeSpan.Zero,
};
}
});
但最有可能的是,这是因为 RsaSecurityKey 包含 RSA-Provider 的实例,并使用它来加密和解密 JWT-Bearer。如果 RSA 实例被处置,这有点问题......
//
// Zusammenfassung:
// Represents a Rsa security key.
public class RsaSecurityKey : AsymmetricSecurityKey
{
public RsaSecurityKey(RSAParameters rsaParameters);
public RsaSecurityKey(RSA rsa);
[Obsolete("HasPrivateKey method is deprecated, please use PrivateKeyStatus.")]
public override bool HasPrivateKey { get; }
public override PrivateKeyStatus PrivateKeyStatus { get; }
public RSA Rsa { get; }
}
只需删除使用,RSA 提供程序可能具有应用程序生命周期范围。然而,这适用于多线程......
推荐阅读
- android - ProgressBar GridView 项
- batch-file - 用于从文本文件列表(Windows)将文件从一个目录移动到另一个目录的批处理脚本
- python - 我可以使用 for 循环从字符串中删除多个索引吗?
- javascript - 如何在 ag 网格中默认折叠侧边栏
- ios - UICollectionView 单元格忽略 UICollectionViewDelegateFlowLayout - sizeForItemAt
- c++ - 我有模板功能。通过使用函数 std::for_each 将每个正数替换为此容器中的最大数
- php - MB_CASE_*_SIMPLE 常量的用途是什么?
- php - 代理的原则设置
- sql-server - 如果用户有权“执行”存储过程,但没有“插入”特定表的访问权限,该存储过程会失败吗?
- c# - 使用枚举作为 FK 的 Entity Framework Core