ASP.NET MVC - 限制用户可以查看/编辑的内容

时间:2017-09-14 15:55:21

标签: c# asp.net-mvc security authorization

我们正在使用Visual Studio 2015 Update 3中的ASP.NET MVC 5应用程序。用户已经通过Identity Framework进行身份验证,我们正在使用授权来限制谁可以访问哪些控制器/操作。但是,我们现在需要更细粒度的东西:在操作上,我们需要限制用户可以查看和编辑的记录。

例如,用户转到GETMyController/Edit/5,我们只希望此用户能够根据某些规则获取他/她有权访问的项目,而不是查看记录只需将URL更改为MyController/Edit/9999(在这种情况下更改ID),即可从其他用户处获得。在某些情况下,规则更复杂,因此并不总是ID。同样的规则也适用于POST行动。

我们正在使用视图模型(VM)向/从视图发送和接收数据。因此,一个VM可能是ItemVm。我们希望该客户只能访问自己的ItemVm而不能访问其他用户。以下是来自控制器的示例:

public async Task<ActionResult> Edit(int id)
{   
    // Only allow users to see "items" they have access to 
    // based on custom rules. If they enter a different ID,
    // prevent them from viewing/editing that information.
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ItemVm itemVm){
    // Only allow users to edit their own "items".
}

This article讨论了基于资源的锁定问题,但不确定在这种情况下是否需要这样做。我们会通过自定义授权属性执行此操作吗?如果是这样,您如何传递ItemVm并应用您的规则?当然,在继续之前,可以在每个动作中添加一个检查;有最好的做法吗?

非常感谢您的帮助。感谢。

2 个答案:

答案 0 :(得分:1)

细节会改变,但可能看起来像这样:

public async Task<ActionResult> Edit(int id)
{   
  // Only allow users to see "items" they have access to 
  // based on custom rules. If they enter a different ID,
  // prevent them from viewing/editing that information.
  string userId = User.Identity.GetUserId();
  var items = context.Items.Where(m => m.Userid == userId);
  return View(items);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ItemVm itemVm){
  // Only allow users to edit their own "items".
  string userId = User.Identity.GetUserId();
  var item = context.Items.Where(m => m.Id == itemVm.ItemId && m.UserId == userId);
  if (item != null)
  {
    //update item stuff
  }
  return View();
}

答案 1 :(得分:1)

专注于你的最后一段。

  

本文讨论了基于资源的锁定,但不确定在这种情况下是否需要。

如果您的项目是使用.NET核心构建的,那么是的。否则,您的项目是使用.NET框架构建的,这意味着该文章无关紧要。

  

我们会通过自定义授权属性执行此操作吗?如果是这样,你如何传递ItemVm并应用你的规则?

假设一个.NET核心项目:不需要自定义授权属性。相反,您将IAuthorizationService依赖项注入Controller(the article,而this video (start at around 27:00)将有更多信息)

  

当然,在继续之前,可以在每个动作中添加一个检查;有最好的做法吗?

不确定最佳做法是什么,但我会创建一个父控制器,它有一个基于当前用户授权资源的方法。