I am using .NET 8.0 and encountering a Cannot access a disposed object (Microsoft.IdentityModel.Tokens.RsaSecurityKey) error about 50% of the time when using the using statement or finally block with rsa.Dispose(). If I do not use using or finally, the error does not occur at all.
Here is my code:
RSA rsa = RSA.Create(); // OR using(RSA rsa = RSA.Create())
try
{
rsa.ImportParameters(new RSAParameters
{
Modulus = bytesN,
Exponent = bytesE
});
var rsaSecurityKey = new RsaSecurityKey(rsa)
{
KeyId = strKid
};
JwtConfiguration jwtConfiguration = _configurationUtil.GetJwtConfiguration("Kakao");
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = jwtConfiguration.ValidateIssuer,
ValidIssuer = jwtConfiguration.ValidIssuer,
ValidateAudience = jwtConfiguration.ValidateAudience,
ValidAudience = jwtConfiguration.ValidAudience,
ValidateLifetime = jwtConfiguration.ValidateLifetime,
RequireExpirationTime = jwtConfiguration.RequireExpirationTime,
ValidateIssuerSigningKey = jwtConfiguration.ValidateIssuerSigningKey,
IssuerSigningKey = rsaSecurityKey,
TryAllIssuerSigningKeys = jwtConfiguration.TryAllIssuerSigningKeys,
};
var tokenHandler = new JwtSecurityTokenHandler();
var claimsPrincipal = tokenHandler.ValidateToken(strIdToken, tokenValidationParameters, out SecurityToken validatedToken);
var jwtSecurityToken = validatedToken as JwtSecurityToken;
string nonce = jwtSecurityToken!.Claims.FirstOrDefault(c => c.Type == "nonce")?.Value!;
if (nonce != oauthConfiguration.Nonce)
throw new Exception("NONCE ERROR");
strId = jwtSecurityToken.Claims.FirstOrDefault(c => c.Type == "sub")?.Value!;
strEmail = jwtSecurityToken.Claims.FirstOrDefault(c => c.Type == "email")?.Value!;
}
catch (Exception e)
{
response.RESULT_CODE = "F000";
response.RESULT_MSG = e.Message;
return Page();
}
finally
{
rsa.Dispose();
}
And here is the exact error message I receive:
IDX10511: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey, KeyId: 'sameKid', InternalId: 'internalId'. , KeyId: sameKid
'.
Number of keys in TokenValidationParameters: '1'.
Number of keys in Configuration: '0'.
Matched key was in 'TokenValidationParameters'.
kid: 'sameKid'.
Exceptions caught:
'System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Security.Cryptography.RSABCrypt'.
at System.Security.Cryptography.RSABCrypt.GetKey()
at System.Security.Cryptography.RSABCrypt.VerifyHash(ReadOnlySpan`1 hash, ReadOnlySpan`1 signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at Microsoft.IdentityModel.Tokens.AsymmetricAdapter.VerifyUsingSpan(Boolean isRSA, ReadOnlySpan`1 bytes, Byte[] signature)
at Microsoft.IdentityModel.Tokens.AsymmetricAdapter.VerifyRsa(Byte[] bytes, Byte[] signature)
at Microsoft.IdentityModel.Tokens.AsymmetricAdapter.Verify(Byte[] bytes, Byte[] signature)
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.Verify(Byte[] input, Byte[] signature)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(Byte[] encodedBytes, Byte[] signature, SecurityKey key, String algorithm, SecurityToken securityToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
'.
token: '[Security Artifact of type 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken' is hidden. For more details, see https://aka.ms/IdentityModel/SecurityArtifactLogging.]'. See https://aka.ms/IDX10511 for details.
How can I properly manage the disposal of the RSA object to avoid this error?
I tried using the using statement and finally block to ensure the RSA object is disposed of properly. I also attempted not using using or finally to avoid the disposal error.
I expected that the signing key would always remain the same, allowing the process to complete without errors and for the validation to succeed. I am not sure why the RSA object is being disposed.
khoo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1