简体   繁体   English

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

[英]ASP.NET MVC - Limit what users can view/edit

We're working on an ASP.NET MVC 5 app in Visual Studio 2015 Update 3. Users are already being authenticated via Identity Framework and we're using authorization to limit who can access which controllers/actions. 我们正在Visual Studio 2015 Update 3中开发ASP.NET MVC 5应用程序。已经通过Identity Framework对用户进行了身份验证,并且我们正在使用授权来限制谁可以访问哪些控制器/操作。 However, we now need something more fine-grained: On the actions, we need to limit what records a user can view and edit. 但是,我们现在需要更细粒度的内容:在操作上,我们需要限制用户可以查看和编辑的记录。

For example, a user goes to the GET version of MyController/Edit/5 , we only want this user to be able to fetch items s/he has access to based on some rules, and not view records from other users by simply changing the URL to MyController/Edit/9999 (changing the ID in this case). 例如,某个用户使用的是MyController/Edit/5GET版本,我们只希望该用户能够根据某些规则来获取他/她有权访问的项目,而不希望仅通过更改该用户来查看其他用户的记录MyController/Edit/9999 URL(在这种情况下,请更改ID)。 In some cases, the rules are more complex, so it's not always the ID. 在某些情况下,规则更加复杂,因此它并不总是ID。 And the same rules apply to POST actions. 同样的规则也适用于POST操作。

We're using view models (VMs) to send and receive data to/from views. 我们正在使用视图模型(VM)向视图发送数据或从视图接收数据。 So one VM might be ItemVm . 因此,一个VM可能是ItemVm We want that customer to only be able to have access to their own ItemVm s and not other users'. 我们希望该客户只能访问自己的ItemVm而不能访问其他用户。 Here's a sample from a controller: 这是来自控制器的示例:

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 talks about locking down based on resources, but wasn't sure if that's what is needed in this case. 本文讨论基于资源的锁定,但不确定在这种情况下是否需要这样做。 Would we do this via a custom authorize attribute? 我们是否可以通过自定义授权属性来做到这一点? If so, how do you pass in the ItemVm and apply your rules? 如果是这样,您如何传入ItemVm并应用规则? Of course, it's possible to add a check inside each and every action before proceeding; 当然,可以在执行每个操作之前在其每个操作中添加检查。 is there a best-practices way? 有没有最佳做法?

Your help is much appreciated. 非常感谢您的帮助。 Thanks. 谢谢。

The specifics would change, but might look something like this: 具体情况会有所变化,但可能看起来像这样:

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

Focusing on your last paragraph. 专注于您的最后一段。

This article talks about locking down based on resources, but wasn't sure if that's what is needed in this case. 本文讨论基于资源的锁定,但不确定在这种情况下是否需要这样做。

If your project is built using .NET core, then yes. 如果您的项目是使用.NET Core构建的,则可以。 Otherwise your project is built using .NET framework, which means the article is irrelevant. 否则,您的项目是使用.NET框架构建的,这意味着本文无关紧要。

Would we do this via a custom authorize attribute? 我们是否可以通过自定义授权属性来做到这一点? If so, how do you pass in the ItemVm and apply your rules? 如果是这样,您如何传入ItemVm并应用规则?

Assuming a .NET core project: A custom authorize attribute is not needed. 假设一个.NET核心项目:不需要自定义授权属性。 Instead, you'll inject the IAuthorizationService dependency into the Controller ( the article and this video (start at around 27:00) will have a lot more information) 相反,您将IAuthorizationService依赖项注入Controller中( 本文该视频(从27:00开始)将提供更多信息)

Of course, it's possible to add a check inside each and every action before proceeding; 当然,可以在执行每个操作之前在其每个操作中添加检查。 is there a best-practices way? 有没有最佳做法?

Not sure what the best-practice would be, but I would create a parent controller which has a method for authorizing resources based on the current user. 不知道最佳实践是什么,但是我将创建一个父控制器,该父控制器具有一种基于当前用户授权资源的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM