繁体   English   中英

MVC C#:验证当前用户有权查看/更新数据

[英]MVC C#: Authenticating current user has rights to view/update data

我们公司目前正在将我们的软件从 Web 表单重新制作为 MVC,并且在我们将其发布给我们的客户之前,它目前处于 alpha 阶段。 简而言之,该应用程序有多家酒店订阅和使用我们的服务。 我现在需要确保的核心安全是没有用户应该能够访问/修改属于另一家酒店的数据。

我们的模型大多遵循以下两个示例之一:

RoomCategory   (structure: model.HotelID)
--------------
ID
HotelID

Room    (structure: model.Parent.HotelID)
--------------
ID
RoomCategoryID
HotelID

问题是,当我在 ~/rooms/edit/1 上时,我可以将表单操作 URL 和隐藏字段值从“1”更改为“50”,并且房间 ID 50 属于另一家酒店。 这是一个大问题,因为一个用户实际上可以从另一家酒店“窃取”一个房间并将其变成自己的房间! 我们的客户不会很高兴。

我处理问题的方式...

从当前登录的用户数据(从会话访问),我们知道用户有权管理的酒店(或酒店)。 一种方法是验证每个动作调用并执行如下操作:

app.AuthenticateAccess(room.RoomCategory.HotelID);

这样,AuthenticateAccess 函数将阻止进一步操作并“重定向”到 Unauthorized/NotFound 页面,因为它知道 Room ID 50 属于 HotelID 2 而当前用户无权访问它。 当然,我认为这是一种安全的方法,但这涉及每个控制器中所有操作的大量重复函数调用。

我一直在寻找在全球范围内克服这一安全挑战的不同可能性:

  1. 最简单。 加密所有 ID 和隐藏字段值,尽管我个人认为即使没有加密,系统也应该能够验证每个用户的访问权限。
  2. 在一个单独的抽象类中设置 HotelID,并让每个模型(存储关于一个特定酒店的数据)从这个抽象类继承。 也许可以在这里完成某种泛型?
  3. 我们使用存储库/工作单元模式。 是否有某种方法可以将我们可以检索/更新的数据限制为仅当前所选酒店 ID 的数据?
  4. [你很棒的解决方案在这里。]

我有一些其他的解决方案,比如使用 System.Reflection 搜索所有 HotelID 属性并确保允许当前用户创建所有保存/创建的数据。 但无论如何,让我听听您解决这个问题的方法,因为我还不相信我能想到的任何解决方案。

永远不要相信来自客户端的数据。 在对数据库进行任何更新/交易之前,始终验证发布的数据。

因此,在您的 HttpPost 操作方法中,您在继续之前运行清理检查

[HttpPost]
public ActionResult Book(BookingViewModel model)
{
  var isGood = hotelService.DoesCurrentUserHasAccessToRoom(model.RoomId);
  if(isGood)
  {
     //Continue with Saving
     hotelService.BookRoom(model);
     return RedirectToAction("BookingCompleted");
  }
  return View("NotAuthorized");
}

只要您根据需要将它们放入服务中的小型可重用方法中,就不会有重复的代码。

其他选项是添加 HMAC 字段来检查敏感数据(隐藏 id 字段)是否未更改,我使用过一次就再也没有使用过,过度解决方案。

话虽如此...

我多次遇到相同的问题,我想过几乎相同的选项,从长远来看,我坚持使用最简单的解决方案 GetById 存储库方法传递CurrentUserId ,例如:

Entity GetById(int id, int? userId);

为什么?

您要求的是粒度级别的授权,只有在您知道操作中涉及的确切记录时才能获得,那么为什么不首先在负责获取记录的方法中进行检查呢?

如果记录存在并且用户创建了该记录,则返回该记录,否则返回 null,因为该用户不存在该对象,甚至不必费心返回“您不拥有该对象”类型的消息,只是一个普通的和简单的 404“记录不存在”。

如果您愿意,您可以尝试使用相同的方法,但使用ActionFilters ,类似于 但是您必须弄清楚如何在该过滤器上下文中检索记录。

对于具有完全访问权限的管理员,如果您将 null 传递给该方法,您可以绕过该检查。

暂无
暂无

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

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