ASP.NET项目中的JWT身份验证 [英] JWT Authentication in ASP.NET Project

查看:271
本文介绍了ASP.NET项目中的JWT身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆