【问题标题】:Security user actions in ASP.Net Core Web APIASP.Net Core Web API 中的安全用户操作
【发布时间】:2020-06-22 15:54:14
【问题描述】:

我使用 JWT 令牌在 ASP.Net Core Web API 中创建用于测试身份验证的项目。我实现了使用帐户的基本功能,但遇到了一些问题。

用户控制器:

[Authorize]
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private readonly IUserService _userService;
    private readonly IAuthenticationService _authenticationService;

    public UsersController(
        IUserService userService,
        IAuthenticationService authenticationService)
    {
        _userService = userService;
        _authenticationService = authenticationService;
    }

    // PUT: users/5
    [HttpPut("{id}")]
    public async Task<ActionResult> PutUser(int id, [FromBody]UpdateUserModel model)
    {
        try
        {
            var user = await _userService.UpdateAsync(model, id);

            return Ok();
        }
        catch(Exception ex)
        {
            return BadRequest(new { message = ex.Message });
        }
    }

    // POST : users/authenticate
    [AllowAnonymous]
    [HttpPost("authenticate")]
    public async Task<ActionResult<User>> Authenticate([FromBody] AuthenticateUserModel model)
    {
        var user = await _authenticationService.AuthenticateAsync(model);

        if (user == null)
            return BadRequest(new { message = "Login or password is incorrect" });

        return Ok(user);
    }
}

身份验证服务:

public async Task<User> AuthenticateAsync(AuthenticateUserModel model)
{
    var users = await _context.Users.ToListAsync();
    var user = users.SingleOrDefault(x => x.Login == model.Login && x.Password == model.Password);

    if (user == null)
        return null;

    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            new Claim(ClaimTypes.Name, user.Id.ToString()),
            new Claim(ClaimTypes.Role, user.Role)
        }),
        Expires = DateTime.UtcNow.AddDays(7),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    user.Token = tokenHandler.WriteToken(token);

    return user.WithoutPassword();
}

事实证明,授权后,如果我们在发送请求的客户端中指定不同的 id,任何用户都可以编辑另一个用户的数据。是否有可能通过令牌以某种方式限制操作,或者这样做更好?

【问题讨论】:

    标签: c# security asp.net-core-webapi jwt-auth


    【解决方案1】:

    您不应信任用户提交的数据。你应该像你自己做的那样在有效载荷数据中设置UserId

     new Claim(ClaimTypes.Name, user.Id.ToString()),
    

    当用户编辑数据时,像这样从JWT 获取用户 ID

    public int GetCurrentUserId()
    {
        var claimsIdentity = _contextAccessor.HttpContext.User.Identity as ClaimsIdentity;
        var userDataClaim = claimsIdentity?.FindFirst(ClaimTypes.Name);
        var userId = userDataClaim?.Value;
        return string.IsNullOrWhiteSpace(userId) ? 0 : int.Parse(userId);
    }
    

    int userId = Convert.ToInt32((User.Identity as ClaimsIdentity).FindFirst(ClaimTypes.Name).Value);
    

    最后

    [HttpPut("PutUser")]
    public async Task<ActionResult> PutUser([FromBody]UpdateUserModel model)
    {
        try
        {
            int userId = Convert.ToInt32((User.Identity as ClaimsIdentity).FindFirst(ClaimTypes.Name).Value);
            var user = await _userService.UpdateAsync(model, userId);
            return Ok();
        }
        catch (Exception ex)
        {
            return BadRequest(new { message = ex.Message });
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-16
      • 2021-08-08
      • 2019-07-09
      • 1970-01-01
      • 2020-06-19
      • 2012-12-19
      • 2017-10-24
      相关资源
      最近更新 更多