【问题标题】:JWT Authentication in ASP.NET ProjectASP.NET 项目中的 JWT 身份验证
【发布时间】:2020-11-01 07:50:28
【问题描述】:

我正在尝试从 JWT 令牌中提取 Id。

控制器代码:

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 但没有错误。

两个错误信息是相同的

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令牌的方法:

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

我想提一下,另一个我使用相同方法的项目,它有效。

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: string 另一个 id: int

如果您需要任何其他信息,请告诉我

编辑: 示例令牌:eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIwMDMzMmVlMy1lZmVlLTRiOTctYTQ5ZS04ODRhYmJhOGE0NzciLCJ1bmlxdWVfbmFtZSI6InJhanUiLCJlbWFpbCI6InJhanVAZ21haWwuY29tIiwicm9sZSI6WyJkZXYiLCJtYW0iXSwibmJmIjoxNTk0NDk1NTA2LCJleHAiOjE1OTUxMDAzMDYsImlhdCI6MTU5NDQ5NTUwNn0.wvfOst-3lMk0d1-LafzuXKzeC_yN2ZQL3GSsZ5114IukOfwipNnTaFm-RlTbu52KesuRl4NyWiHoEt5IR0n7EQ

解码令牌的有效载荷:

【问题讨论】:

    标签: c# asp.net authentication asp.net-web-api jwt


    【解决方案1】:

    已编辑:

    您的令牌似乎没有 Sub 声明,该声明将映射到 ClaimTypes.NameIdentifier(又名 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

    另外,我希望您将令牌保存在 AppSettings 中只是为了测试目的,因为令牌是要过期的。

    【讨论】:

    • 是的,它有 Id、Email、Role、Exp_date
    • 您自己创建了令牌吗?可以在那里添加一个“Sub”,其中“sub”是一个唯一的 id(所以是 id 或 email)。
    • 我将 ClaimTypes.NameIdentifier, user.Id.ToString() 替换为 JwtRegisteredClaimNames.Sub, user.Id 没有任何改变
    猜你喜欢
    • 2017-05-13
    • 2019-09-06
    • 2017-07-30
    • 2021-04-20
    • 2017-03-09
    • 2017-12-06
    相关资源
    最近更新 更多