I'm currently running into an issue with decrypting jwts using a public key. When I use the RSA class with a using declaration (I did try the older syntax too just to be safe), I get 401s every time. Removing the using keyword fixes the problem, but I'm sure that's poor practice as RSA is an IDisposable. Any ideas on how to make this work the proper way?
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,
};
});
I did find a self-answer here RSA Disposed Object Error - every other test, but isn't omitting "using" an incorrect use of IDisposable objects?
I'll also note this is not the same as the caching issue in which it returns 200 once and 401 after that. The code currently returns 401 every time.
How about setting the using-clause in curly brackets, so it doesn't get disposed after the next instruction ?
But most-likely, this is because RsaSecurityKey has the instance of the RSA-Provider contained, and uses that to encrypt and decrypt the JWT-Bearer. Which is a bit of a problem if the RSA instance is disposed ...
Just remove the using, the RSA-provider probably has application-lifetime scope. However that works with MultiThreading...