验证 JWT 得到一个奇怪的“无法匹配关键孩子”错误
Posted
技术标签:
【中文标题】验证 JWT 得到一个奇怪的“无法匹配关键孩子”错误【英文标题】:Validating JWT getting a strange “ Unable to match key kid” error 【发布时间】:2020-08-28 21:13:51 【问题描述】:我正在尝试使用下面的代码验证有效的 JWT,但遇到了一个奇怪的错误
"IDX10501: Signature validation failed. Unable to match key:
kid: 'System.String'.
Exceptions caught:
'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'."
这是我的验证方法
ClaimsPrincipal principal = null;
var token = "JWT GOES HERE"
try
string sec = "000uVmTXj5EzRjlnqruWF78JQZMT";
var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
var now = DateTime.UtcNow;
SecurityToken securityToken;
string tokenIssuer = "https://MyIssuer.com";
TokenValidationParameters validationParameters = new TokenValidationParameters()
ValidIssuer = tokenIssuer,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = securityKey
;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
principal = handler.ValidateToken(token, validationParameters, out securityToken); <---Errors here
这是我的 JWT 的值。我正在使用正确的发行人
"alg": "RS256",
"kid": "dev",
"x5t": "Sm7aAUSt4Fdv7X1b9jQDf8XwbvQ",
"pi.atm": "xxe8"
.
"scope": [],
"client_id": "ClientABC",
"iss": "https://MyIssuer.com",
"jti": "1JLDz",
"sub": "ClientABC",
"exp": 1601609852
.[Signature]
我在这里缺少什么?因为这个算法是 RS256,所以是 SymmetricSecurityKey 吗?我的 TokenValidationParameter 中是否缺少某些内容?
更新 经过进一步调查,我得到了错误。
IDX10501: Signature validation failed. Unable to match key:
kid: 'dev'.
Exceptions caught:
'System.NotSupportedException: IDX10634: Unable to create the SignatureProvider.
Algorithm: 'RS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: 'TdfWgWjCVeM60F3C5TOogJuka1aR5FA_xchwhY9MHH4'.'
is not supported. The list of supported algorithms is available here: https://aka.ms/IdentityModel/supported-algorithms
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures, Boolean cacheProvider)
【问题讨论】:
嘿,如果SymetricSecurityKey编码不是ASCII ```` new SymmetricSecurityKey(Encoding.ASCII.GetBytes(sec)) ```` 我不太确定应该是什么,这就是我问的原因 指定使用的KeyId有帮助吗?var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec)) KeyId = "dev" ;
【参考方案1】:
尝试使用 SecurityAlgorithms.HmacSha256
颁发令牌时的示例:
Users user = _context.Users.FirstOrDefault(c => c.UserName == userName && c.Password == password);
if(user == null)
return Unauthorized();
Claim[] claims = new Claim[]
new Claim("Id", user.Id.ToString()),
new Claim("Name", user.Name),
new Claim("Email", user.Email),
;
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("000uVmTXj5EzRjlnqruWF78JQZMT"));
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var token = new
JwtSecurityToken(
"MyProject",
"MyClient",
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: signingCredentials);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
如果您使用的是 .net core 应用程序,则在 Startup.cs 中,在 ConfigureServices 方法中编写以下代码来验证令牌:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = "MyClient",
ValidIssuer = "MyProject",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("000uVmTXj5EzRjlnqruWF78JQZMT"))
;
);
另外不要忘记将以下行添加到 Startup.cs
中的 Configure 方法中app.UseAuthentication();
app.UseAuthorization();
【讨论】:
不是我在这个 libe 上做的事情 var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec)); 我编辑了答案以显示示例,请检查它【参考方案2】:问题是您正在尝试将对称密钥与非对称算法一起使用。 RSA 算法需要公钥和私钥。
尝试改用对称算法,例如 HS256 (HMAC-SHA256)。
【讨论】:
这行不是在做什么 var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));我还需要什么? 在 JWT 的标头中指定 RS256 算法。以上是关于验证 JWT 得到一个奇怪的“无法匹配关键孩子”错误的主要内容,如果未能解决你的问题,请参考以下文章