log*_*060 1 linux containers jwt docker .net-core
在.net core 2.2中,当我对应用程序进行容器化时,出现Bearer错误=“ invalid_token”,error_description =“签名无效”
当我使用IIS / IIS Express在Windows上托管它时,它运行良好。
我的代码-令牌生成器是IBM API Connect,它使用RSA 256算法生成密钥
var rsa = new RSACryptoServiceProvider();
string exponentvalue = "AQAB";
var e = Base64UrlEncoder.DecodeBytes(exponentvalue);
var N = "public key put your value here"
var modulus = Base64UrlEncoder.DecodeBytes(N);
rsa.ImportParameters(
new RSAParameters()
{
Modulus = modulus,
Exponent = e
});
var signingKey = new RsaSecurityKey(rsa);
Run Code Online (Sandbox Code Playgroud)
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = false,
ValidIssuer = issuer,
// Validate the JWT Audience (aud) claim
ValidateAudience = false,
ValidAudience = audience,
// Validate the token expiry
//ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
//ClockSkew = TimeSpan.FromMinutes(1)
};
Run Code Online (Sandbox Code Playgroud)
知道为什么它不能在docker或AKS本地托管的容器上工作吗?
经过几天的研究和尝试不同的东西终于解决了我的问题。
@bartonjs提到了第一个问题,这里在.NET核心中实现RSA我不得不使用RSA.Create()而不是RSACryptoServiceProvider()。
如上一篇文章中所建议,第二个问题是我使用(using)语句实现了该问题,而该声明在Linux中不起作用。来自@bartonjs对这篇文章的评论https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/994看起来像是引入了一个错误“我们可能在处理后意外地引入了一个错误与刚创建的相同,它认为只需要在首次使用(在本例中为下一个)上构成关键。”
适用于Linux和Windows的最终代码
public class JwtConfiguration : IDisposable
{
/// <summary>
/// Configures the JWT Token Validation parameters.
/// </summary>
/// <param name="Configuration">
/// ASP.NET Core Configuration object instance.
/// </param>
/// <returns>
/// A TokenValidationParameters object instance.
/// </returns>
private RSA _publicRsa;
private SecurityKey _issuerSigningKey;
public TokenValidationParameters GetTokenValidationParameters(IConfiguration Configuration)
{
var issuer = Configuration["Jwt:Issuer"];
if (string.IsNullOrWhiteSpace(issuer))
{
throw new MissingJwtTokenParameterException("Missing Jwt:Issuer value.");
}
var audience = Configuration["Jwt:Audience"];
if (string.IsNullOrWhiteSpace(audience))
{
throw new MissingJwtTokenParameterException("Missing Jwt:Audience value.");
}
var secretKey = Configuration["Jwt:Key"];
if (string.IsNullOrWhiteSpace(secretKey))
{
throw new MissingJwtTokenParameterException("Missing Jwt:Key value.");
}
string exponentvalue = "AQAB";
var e = Base64UrlEncoder.DecodeBytes(exponentvalue);
var modulus = Base64UrlEncoder.DecodeBytes(secretKey);
_publicRsa = RSA.Create();
_publicRsa.KeySize = 3072;
_publicRsa.ImportParameters(
new RSAParameters()
{
Modulus = modulus,
Exponent = e
});
_issuerSigningKey = new RsaSecurityKey(_publicRsa);
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = _issuerSigningKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = issuer,
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = audience,
//Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.FromMinutes(1)
};
return tokenValidationParameters;
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
_publicRsa?.Dispose();
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
~JwtConfiguration() {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
}
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
GC.SuppressFinalize(this);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)