JwtBearerAuthentication安全处理异常

本文关键字:异常 处理 安全 JwtBearerAuthentication | 更新日期: 2023-09-27 18:06:12

当使用JwtBearerAuthentication中间件时,在JwtSecurityTokenHandler.WriteToken()被调用后,RSACryptoServiceProvider和其他对象在SigningCredentials中被处置。我的问题和这个问题很相似:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/477.

第一个请求成功,但所有后续请求都失败。这个功能在RC2中工作得很好……但是现在我们已经升级到1.0了,WriteToken的结果是:

System.ObjectDisposedException was unhandled by user code HResult=-2146232798 Message=Safe handle has been closed ObjectName="" Source=mscorlib StackTrace: at System.Security.Cryptography.Utils._GetKeyParameter(SafeKeyHandle hKey, UInt32 paramID) at System.Security.Cryptography.RSACryptoServiceProvider.get_KeySize() at Microsoft.IdentityModel.Tokens.RsaSecurityKey.get_KeySize() at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.ValidateAsymmetricSecurityKeySize(SecurityKey key, String algorithm, Boolean willCreateSignatures) at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures) at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures) at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token) at Api.Controllers.TokenController.CreateToken(EmployeeSecurityRecord record, DateTime expires) in C:'SOURCE'Api'Procede.Excede.Api.Core'src'Api'Controllers'TokenController.cs:line 115 at Api.Controllers.TokenController.Post(ResourceTokenRequest request) in C:'SOURCE'Api'Procede.Excede.Api.Core'src'Api'Controllers'TokenController.cs:line 35 at lambda_method(Closure , Object , Object[] ) at Microsoft.AspNetCore.Mvc.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionFilterAsync>d__28.MoveNext() InnerException:

我也找不到任何关于正确使用JwtBearerAuthentication的优秀文档。任何想法吗?这是我的实现…

在Startup.cs:

ConfigureServices:

        var keyFile = Configuration["AppSettings:Secret"];
        var keyParams = RSAKeyUtils.GetKeyParameters(Path.Combine(Environment.ContentRootPath, keyFile));
        var provider = new RSACryptoServiceProvider();
        provider.ImportParameters(keyParams);
        var key = new RsaSecurityKey(provider);
        _tokenOptions = new TokenAuthOptions
        {
            Audience = Configuration["AppSettings:Audience"],
            Issuer = Configuration["AppSettings:Issuer"],
            TokenLife = Convert.ToInt32(Configuration["AppSettings:TokenLife"]),
            Key = key,
            SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature)
        };
配置:

        app.UseJwtBearerAuthentication(new JwtBearerOptions
        {
            TokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningKey = _tokenOptions.Key,
                ValidAudience = _tokenOptions.Audience,
                ValidIssuer = _tokenOptions.Issuer,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromMinutes(1)
            }
        });

通过控制器方法创建令牌:

    private string CreateToken(EmployeeSecurityRecord record, DateTime expires)
    {
        var identity = new ClaimsIdentity(
            new GenericIdentity(record.EmpId, "TokenAuth"),
            new[]
            {
                new Claim("tid", "TBD", ClaimValueTypes.String),
                new Claim("branch_id", record.BrnId, ClaimValueTypes.String),
                new Claim("wid", record.WspId.ToString(), ClaimValueTypes.Integer),
                new Claim("roles", "TBD", ClaimValueTypes.String),
                new Claim("alt_sub", record.AltEmpId ?? "", ClaimValueTypes.String),
                new Claim("alt_wid", record.AltWspId == null ? "" : record.AltWspId.ToString(),
                    ClaimValueTypes.Integer),
                new Claim("alt_roles", "TBD", ClaimValueTypes.String)
            });
        var handler = new JwtSecurityTokenHandler();
        var descriptor = new SecurityTokenDescriptor
        {
            Issuer = _tokenOptions.Issuer,
            Audience = _tokenOptions.Audience,
            SigningCredentials = _tokenOptions.SigningCredentials,
            Subject = identity,
            Expires = expires
        };
        var token = handler.CreateToken(descriptor);
        return handler.WriteToken(token);

JwtBearerAuthentication安全处理异常

From Microsoft team on Github:

库正在处理一个不是它创建的rsa对象。如果我们修复了这个问题,一个可能的解决方案是基于JwtSecurityTokenHandler调用CryptoProviderFactory。创建签名后释放签名提供商。你可以设置自己的CPF并覆盖ReleaseSignatureProvider。RSP位于将处理rsa的调用图中。SigningCredentials。CryptoProviderFactory是一个方便的地方设置您的CustomProviderFactory。

如果我有时间,我可能会尝试覆盖解决方案…否则,我将等待5.0.1版本发布。

GitHub链接