检查模型对象所有权的 ASP.NET 最佳实践



现在我像下面的代码一样检查用户的对象所有权(我对代码的重要部分进行了评论(。我对应用程序中的每个模型和每个控制器方法都这样做,这完全违反了DRY原则。也许你对我如何避免重复有一些想法?

此外,我不确定它是否安全,用户也无法通过一些技巧访问他人的数据。我所做的是安全的吗?

这是关于个人数据安全的一个非常重要的话题,我相信应该有一些文档。不幸的是,我没有找到任何文档,如果我搜索不好,我会很高兴看到任何链接。

任务控制器.cs

public async Task<IActionResult> Index()
{
// here I form a selection from objects belonging to the current user
var Tasks = _context.Tasks.Where(t => t.UserId.Equals(User.Identity.GetUserId()));
return View(await applicationDbContext.ToListAsync());
}

public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var task = await _context.Tasks.FindAsync(id);
// here I check if the requested object belongs to the current user
if (task == null | task.UserId != User.Identity.GetUserId())
{
return NotFound();
}
return View(task);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,TaskTypeId,Status,UserId")] Task task)
{
if (ModelState.IsValid)
{
// here i am assigning object's UserId to id of current user
task.UserId = User.Identity.GetUserId();
_context.Add(task);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(task);
}

我认为最好的方法是向控制器注入一个工作上下文对象。然后从该对象中获取用户和其他常见信息,这将减少重复代码。例如:

控制器:

private readonly IWorkContext _workContext;
public MyController(IWorkContext  workContext)
{
this._workContext = workContext;
}

操作:

而不是User.Identity.GetUserId(),而是_workContext.UserId。这样,如果您的身份逻辑发生了变化,那么您不必在数百个地方进行更改,而只需在IWorkContext中进行更改。

以下是IworkContext实现中的内容:

public partial class WorkContext : IWorkContext
{
...
public virtual string UserId
{
get
{
return User.Identity.GetUserId()
}
}
}

您可以相应地定义IWorkContext接口,并在其中实现必要的基于用户的逻辑。

您也可以在工作上下文对象中拥有Task属性,而不是在不同的操作中。

我没有包含上面的依赖注入相关代码示例。这不是问题的一部分。您可以在此处阅读有关依赖注入的更多信息。

最新更新