我们正在使用Visual Studio 2015 Update 3中的ASP.NET MVC 5应用程序。用户已经通过Identity Framework进行身份验证,我们正在使用授权来限制谁可以访问哪些控制器/操作。但是,我们现在需要更细粒度的东西:在操作上,我们需要限制用户可以查看和编辑的记录。
例如,用户转到GET
版MyController/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
并应用您的规则?当然,在继续之前,可以在每个动作中添加一个检查;有最好的做法吗?
非常感谢您的帮助。感谢。
答案 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)将有更多信息)
当然,在继续之前,可以在每个动作中添加一个检查;有最好的做法吗?
不确定最佳做法是什么,但我会创建一个父控制器,它有一个基于当前用户授权资源的方法。