在检索并提交对SQL的更改时,是否检查UserId足够安全?

时间:2014-02-11 19:06:50

标签: sql entity-framework asp.net-identity

我正在尝试确保用户无法访问或修改属于其他用户的表中的行。经过一些研究,这是我提出的方法(示例代码)

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操作发生之前。

这是否足够安全,是否是阻止人们访问彼此数据的有效方式,还是我应该实施另一项安全检查?

1 个答案:

答案 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语句中减少您需要写入的验证逻辑量。它还使得为其他用户获取或删除记录绝对不可能。