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.
You
Dispose
objects when you're sure you no longer require them.Here, you may be issuing tokens at any time that your application is running. So
Dispose
-ing of the object whilst still configuring the application is wrong.I'd suggest, here, that you don't
Dispose
the object. The only time you actually know that it's no longer required is when the application is shutting down - but in that case, you know that everything in the process is about to be destroyed - there's no point delaying that just to do a bit of tidying that nobody will benefit from.