我正在 .net core 3.1 中生成 JWT token ,如下所示
private string GenerateJwtToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_authenticationSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.Username),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.GivenName, user.FirstName)
}),
Expires = DateTime.UtcNow.AddDays(_authenticationSettings.AuthTokenValidityInDays),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
在我的单元测试中,我尝试像这样测试它
[Fact]
public async Task Should_Authenticate_With_Valid_CredentialsAsync()
{
var tokenString = await _sut.Authenticate(new User
{
Username = "test",
Email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3d49584e497d5b5c5658505c5451135e5250" rel="noreferrer noopener nofollow">[email protected]</a>",
FirstName = "Someone"
});
var jwtHandler = new JwtSecurityTokenHandler();
Assert.True(jwtHandler.CanReadToken(tokenString));
var token = new JwtSecurityToken(tokenString);
Assert.Equal("test", token.Claims.First(claim => claim.Type == ClaimTypes.NameIdentifier).Value);
}
第一个 Assert
通过,但第二个由于空引用异常而失败。我检查了代码并查看了 nameid
类型的用户名声明。测试期间,键 ClaimTypes.NameIdentifier
的值似乎是 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
而不是 nameid
。
有人可以帮助解释发生了什么以及如何解决它吗?
最佳答案
好吧,经过一番深入研究,我终于找到了答案。所以我需要做的是这样的事情(它获取一个可以使用静态类型查询的 ClaimsPrincipal
)
var validationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes("my-super-secret-test-key")), SecurityAlgorithms.HmacSha256Signature).Key,
ValidateAudience = false,
ValidateIssuer = false,
};
SecurityToken validatedToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var user = handler.ValidateToken(tokenString, validationParameters, out validatedToken);
Assert.Equal("test", user.FindFirst(ClaimTypes.NameIdentifier).Value);
关于c# - .net core 解码的 JWT 声明类型与生成时使用的类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62548869/