问题描述
在 .net core 2.2 中,当我容器化应用程序时,我收到一个 Bearer error="invalid_token", error_description="The signature is invalid"
In .net core 2.2 when i containerize the app i get a Bearer error="invalid_token", error_description="The signature is invalid"
当我使用 IIS/IIS express 在 Windows 上托管它时它工作正常.
It is working fine when i host it on windows using IIS/IIS express.
我的代码 -- 令牌生成器是 IBM API Connect,它使用 RSA 256 算法生成密钥
My code -- The token generator is IBM API Connect it uses RSA 256 Algorithm to generate the key
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);
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)
};
知道为什么它不能在本地托管在 docker 或 AKS 上的容器上工作吗?
Any idea why it wouldn't be working on a container hosted either locally on docker or AKS?
推荐答案
经过几天的研究和尝试不同的东西终于解决了我的问题.
After few days of researching and trying different things have finally Resolved my issue.
@bartonjs 在这里提到了第一个问题 在 .NET 核心中实现 RSA 我不得不使用 RSA.Create() 而不是 RSACryptoServiceProvider().
First Issue was as mentioned by @bartonjs here implement RSA in .NET core I had to use RSA.Create() Instead of RSACryptoServiceProvider().
上面帖子中推荐的第二个问题我正在使用(使用)语句实现它,但在 Linux 中不起作用.来自 @bartonjs 对这篇文章的评论 https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/994 看起来像是引入了一个错误我们可能不小心引入了一个错误,其中 post-dispose 与新创建的相同,在那里它认为它只需要在第一次(在本例中为下一步)使用时补上一个键即可."
Second Issue as recommended in above post i was implementing it with (using) statement which was not working in Linux. From @bartonjs comments on this post https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/994 it looks like a bug introduced "We might have accidentally introduced an error where post-dispose is the same as freshly created, where it thinks it needs to just make up a key on first (next, in this case) use."
适用于 Linux 和 Windows 的最终代码
Final code that works both on Linux and 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
}
这篇关于.Net Core 2.2 验证 jwt 在容器上失败并显示 401的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!