Аутентификация JWT в ASP. NET Project - PullRequest
0 голосов
/ 11 июля 2020

Я пытаюсь извлечь идентификатор из токена JWT .

Код контроллера:

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);
        }

Но это показывает ошибку времени выполнения.

Если я удалю .Value (закомментированная строка) (User.FindFirst(ClaimTypes.NameIdentifier), он вернет null, но без ошибок.

Error stack from Postman Error stack from VS Code Both error messages are identical

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
                    };
                });

Method that generate JWT token:

private async Task GenerateJwtToken(User user)
        {
            var claims = new List {
                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 GetUser(int id)
        {
            var isCurrentUser = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value) == id;
            var user = await _repo.GetUser(id, isCurrentUser);
            var userToReturn = _mapper.Map(user);
            return Ok(userToReturn);
        }

Difference is, one have id: string another id: int

Please let me know, If you need any additional Info

Edit: Example Token: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIwMDMzMmVlMy1lZmVlLTRiOTctYTQ5ZS04ODRhYmJhOGE0NzciLCJ1bmlxdWVfbmFtZSI6InJhanUiLCJlbWFpbCI6InJhanVAZ21haWwuY29tIiwicm9sZSI6WyJkZXYiLCJtYW0iXSwibmJmIjoxNTk0NDk1NTA2LCJleHAiOjE1OTUxMDAzMDYsImlhdCI6MTU5NDQ5NTUwNn0.wvfOst-3lMk0d1-LafzuXKzeC_yN2ZQL3GSsZ5114IukOfwipNnTaFm-RlTbu52KesuRl4NyWiHoEt5IR0n7EQ

Payload of Decoded Token: Расшифрованный токен

1 Ответ

0 голосов
/ 11 июля 2020

Отредактировано:

Похоже, ваш токен не имеет заявки Sub, которая будет сопоставлена ​​с ClaimTypes.NameIdentifier (он же http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier)

Кроме того, я надеюсь, что вы экономите токен в AppSettings только для целей тестирования, поскольку срок действия токенов истек.

...