使用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);
答案 0 :(得分:0)
来自Github上的微软团队:
库正在处理它没有创建的rsa对象。我们得到修复的一个可能的解决方法是基于JwtSecurityTokenHandler在创建签名后调用CryptoProviderFactory.ReleaseSignatureProvider。您可以设置自己的CPF并覆盖ReleaseSignatureProvider。 RSP位于将配置rsa的调用图中。 SigningCredentials。 CryptoProviderFactory是设置CustomProviderFactory的便利位置。
如果我有时间,我可以尝试覆盖解决方案......否则,我会等待5.0.1版本发布。