ASP.Net Core Web API 中的安全用户操作

Posted

技术标签:

【中文标题】ASP.Net Core Web API 中的安全用户操作【英文标题】:Security user actions in ASP.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,任何用户都可以编辑另一个用户的数据。是否有可能通过令牌以某种方式限制操作,或者这样做更好?

【问题讨论】:

【参考方案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 );
    


【讨论】:

以上是关于ASP.Net Core Web API 中的安全用户操作的主要内容,如果未能解决你的问题,请参考以下文章

ASP.Net Core Web Api 中的异步视频流不起作用

这是从 ASP.NET Core Web API 中的 EF Core 5 获得的啥样的响应 [关闭]

ASP.Net Core 3.1 - Web API 中的 Post 参数始终为 NULL

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

如何保护 ASP.NET Core Web API 免受被盗 JWT 令牌以进行模拟

匿名端点重定向到安全 ASP.Net Core Web 应用程序中的登录屏幕