JwtBearerAuthentication安全处理异常 [英] JwtBearerAuthentication Safe Handle Exception

查看:76
本文介绍了JwtBearerAuthentication安全处理异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用JwtBearerAuthentication中间件时,在调用JwtSecurityTokenHandler.WriteToken()之后,将RSACryptoServiceProvider和其他对象放在SigningCredentials中.我的问题与此问题非常相似: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/477 .

When using the JwtBearerAuthentication middleware, The RSACryptoServiceProvider and other objects are disposed in the SigningCredentials after JwtSecurityTokenHandler.WriteToken() is called. My issue is very similiar to this issue: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/477.

第一个请求有效,但是任何后续请求均失败.此功能在RC2中效果很好...但是现在我们已经升级到1.0,WriteToken的结果是:

The first request works, but any subsequent requests fail. This functionality worked great in RC2... but now that we've upgrade to 1.0, WriteToken results in:

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的出色文档.有什么想法吗?这是我的实现...

I can't find any great documentation on proper usage of the JwtBearerAuthentication either. Any thoughts? Here is my implementation...

在Startup.cs中:

In Startup.cs:

ConfigureServices:

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)
            }
        });

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

Creating the token via a controller method:

    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);

推荐答案

来自Microsoft在Github上的团队:

From the Microsoft team on Github:

库正在处理未创建的rsa对象.我们得到修复的一种可能的解决方法是基于创建签名后调用CryptoProviderFactory.ReleaseSignatureProvider的JwtSecurityTokenHandler.您可以设置自己的CPF并覆盖ReleaseSignatureProvider. RSP位于将配置rsa的调用图中. SigningCredentials. CryptoProviderFactory是设置CustomProviderFactory的便捷位置.

The library is disposing an rsa object it didn't create. A possible workaround it we get this fixed is based on JwtSecurityTokenHandler calling CryptoProviderFactory.ReleaseSignatureProvider after creating the signature. You can set your own CPF and override ReleaseSignatureProvider. RSP is in the call graph that will dispose the rsa. SigningCredentials. CryptoProviderFactory is a convenient place to set your CustomProviderFactory.

如果有时间,我可以尝试使用替代解决方案...否则,我将等待5.0.1版本发布.

I may try the override solution if I have time...otherwise, I'll wait for the 5.0.1 version to be release.

GitHub链接

这篇关于JwtBearerAuthentication安全处理异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆