ASP.NET项目中的JWT身份验证 [英] JWT Authentication in ASP.NET Project
问题描述
我正在尝试从 JWT令牌提取ID.
I am Trying to extract the Id from JWT Token.
控制器代码:
public async Task<IActionResult> GetUser(string id)
{
var currentUserId = (User.FindFirst(ClaimTypes.NameIdentifier).Value); //Line number: 27
bool isCurrentUser = String.Equals(currentUserId, id);
var user = await _repo.GetUser(id, isCurrentUser);
var userToReturn = _mapper.Map<UserForDetailed>(user);
return Ok(userToReturn);
}
但这显示了运行时错误.
But this shows a run time error.
如果我删除.Value(注释行)(User.FindFirst(ClaimTypes.NameIdentifier)
,它将返回null,但没有错误.
If I remove .Value (commented line) (User.FindFirst(ClaimTypes.NameIdentifier)
it returns null but no error.
两个错误消息都是相同的
Startup.cs:
Startup.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration
.GetSection("AppSettings:Token").Value)),
ValidateIssuer = true,
ValidateAudience = true
};
});
生成JWT令牌的方法:
Method that generate JWT token:
private async Task<string> GenerateJwtToken(User user)
{
var claims = new List<Claim> {
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.Email, user.Email)
};
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(7),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
我想提一下,另一个使用相同方法的项目,它可以正常工作.
I like to mention, another project where I used the same method, it works.
public async Task<IActionResult> GetUser(int id)
{
var isCurrentUser = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value) == id;
var user = await _repo.GetUser(id, isCurrentUser);
var userToReturn = _mapper.Map<UserForDetailed>(user);
return Ok(userToReturn);
}
区别在于,一个具有id:字符串,另一个具有id:int
Difference is, one have id: string another id: int
请让我知道,如果您需要任何其他信息
令牌示例:eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIwMDMzMmVlMy1lZmVlLTRiOTctYTQ5ZS04ODRhYmJhOGE0NzciLCJ1bmlxdWVfbmFtZSI6InJhanUiLCJlbWFpbCI6InJhanVAZ21haWwuY29tIiwicm9sZSI6WyJkZXYiLCJtYW0iXSwibmJmIjoxNTk0NDk1NTA2LCJleHAiOjE1OTUxMDAzMDYsImlhdCI6MTU5NDQ5NTUwNn0.wvfOst-3lMk0d1-LafzuXKzeC_yN2ZQL3GSsZ5114IukOfwipNnTaFm-RlTbu52KesuRl4NyWiHoEt5IR0n7EQ
解码令牌的有效载荷:
Payload of Decoded Token:
推荐答案
您的令牌似乎没有Sub
声明,该声明将被映射到ClaimTypes.NameIdentifier
(又名http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
)
Your token does not seem to have a Sub
claim which will be mapped to ClaimTypes.NameIdentifier
(aka http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
)
此外,我希望您将令牌保存在AppSettings中只是出于测试目的,因为令牌本来应该过期的.
Also, I hope you are saving the token in the AppSettings just for testing purposes, because Tokens are meant to be expired.
这篇关于ASP.NET项目中的JWT身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!