ViewModel中的ASP.NET模型ID - 安全吗?

时间:2016-11-30 19:24:47

标签: asp.net-mvc security model mapping viewmodel

方案: (使用ASP.NET Web应用程序 - Core或MVC)

我为每个用户提供了一个包含UsersItems的数据库。 这意味着UserIdforeign key表中的Items

我从浏览器登录User。我将Items作为ItemViewModels的列表,通过简单的api GET请求将其映射(AutoMapper)到ItemViewModels

我想通过简单的API调用更新其中一个项目(应该属于我 - 登录用户)。所以我通过PUT请求将修改后的项目作为ItemViewModel发送回服务器。

  

第一种方法:

最简单的方法是在ItemId中包含项目的数据库ID ItemViewModel - 所以当我收到要更新为ItemViewModel的项目时,我可以映射它返回数据库中的现有项目。

然而,这对我来说听起来非常不安全,因为任何人都可以使用任何ItemId修改PUT请求,并影响不属于执行请求的用户的项目。这种方法有什么我想念的吗?

  

第二种方法:

请勿在{{1​​}}中传递数据库PK ItemId。 而是使用其他形式的标识:假设用户ItemViewModel有10个项目。它们使用名为X的属性(也存在于数据库中)从1到10编号。

然后,我可以在UserItemId中传递此UserItemId,当我将其恢复时,我可以将其映射到数据库中的现有项目(如果请求一切正常)或丢弃它如果ItemViewModel与登录用户的项目中的任何内容都不匹配,则拒绝该请求。

有人使用这种方法吗?

优点

用户只能访问自己的项目,并且不会影响其他任何人,因为它不知道实际的项目ID(主键),并且任何修改仅限于它的项目。

缺点

必须在服务器端实施大量额外管理才能使用此方法。

  

还有其他方法吗?

请考虑上述情况适用于数据库中客户端实现可以CRUD的所有实体,因此不仅仅是上述的简单情况。

建议的解决方案应适用于整个应用数据。

我知道这个问题已被问到herehere但是第一个问题没有令人满意的答案,我认为第二个问题并不适用于我的情况,因为它只是处理UserId。

感谢。

  

修改

请将上面的UserItemId视为聚合根,其中包含多个复杂Item,每个复合subItems都包含一个表格。这个问题适用于主要Item。这意味着每个subItem都作为ViewModel传递给客户端。

我应该提及有关进一步确保更新请求的安全性:

  1. 对于第一种方法,我可以轻松检查是否允许用户更改项目。但我也应该为所有subItems执行此操作。

  2. 对于第二种方法,我可以检查用户是否可以按如下方式更新Item:我得到传入的ViewModel的userItemId - >我从数据库中获取所有已登录用户的项目并尝试查找与相同userItemId的匹配项,如果我获得了点击,则继续进行更新。

1 个答案:

答案 0 :(得分:0)

如果您只隐藏ID,我认为您的应用程序不安全。 在更改数据库实体之前,必须检查是否允许用户更改实体。 在您的情况下,如果您的身份验证用户中的Id是您商品中的UserId,则应该进行检查。 如果您的ViewModel与您的API相似或相同,则可以在控制器中使用FilterAttribute。