我正在尝试确保用户无法访问或修改属于其他用户的表中的行。经过一些研究,这是我提出的方法(示例代码)
public virtual ActionResult Edit(int id)
{
var myEntity = myEntityService.GetEntity(id);
if (myEntity == null)
return HttpNotFound();
if (myEntity.UserId != User.Identity.GetUserId())
return HttpNotFound();
MyEntityFormModel editMyEntity = Mapper.Map<MyEntity, MyEntityFormModel>(myEntity);
return View(editMyEntity);
}
}
其他CRUD操作的类似方法:通过Id检索实体,然后检查以确保实体的UserId属性(从AspNet.Identity.GetUserId()检索并在创建期间存储)与用户UserId匹配在允许任何CRUD操作发生之前。
这是否足够安全,是否是阻止人们访问彼此数据的有效方式,还是我应该实施另一项安全检查?
答案 0 :(得分:1)
我没有使用EF来了解该框架中可能的具体内容,但这是我在nHibernate中所做的。
对于GetEntity,请在查询参数中使用Id和UserId来获取。 它可以节省sql server负载,带宽和网络使用量,因为如果实体对签名用户无效,则不会返回任何不必要的数据。
插入:不会出现问题,因为您无论如何都需要将entity.UserId设置为已签名的用户ID。
更新:您可能需要手动验证entity.UserId是否与已登录用户的ID匹配。但是检查EF是否有办法“更新实体,其中Id = X和UserId = Y” - 从长远来看,它将使这更安全,更容易维护。
删除:与GetEntity相同 - 通过Id和UserId进行删除作为查询参数。因此,如果记录不是当前用户,则不会删除任何内容。
我想一般的方法几乎就像将实体视为在Id和UserId上有复合键一样。
所以MyEntityDbContext看起来像这样
interface IMyEntityDbContext {
Entity GetEntity(int id, int userId);
int Insert(Entity entity);
void Delete(int id, int userId);
void Update(Entity entity);
//or if possible in EF
void Update(Entity entity, int userId);
}
它只会在Update语句中减少您需要写入的验证逻辑量。它还使得为其他用户获取或删除记录绝对不可能。