2014-02-11 20 views
0

我試圖確保用戶不能訪問或修改屬於其他用戶的表中的行。之後的所作所爲一些研究,這是方法我已經想出了(示例代碼)在檢索並提交對EF的SQL更改並且提交足夠安全之前檢查UserId?

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的實體,然後檢查,以確保用戶ID實體的屬性(從AspNet.Identity.GetUserId()中檢索並在創建期間存儲)與允許任何CRUD操作發生之前的用戶UserId匹配。

這是否足夠安全並且是一種讓人們不能訪問彼此數據的有效方式,還是應該實施另一項安全檢查?

回答

1

我還沒有用EF來了解該框架中可能的細節,但這是我在nHibernate中要做的。

對於GetEntity,請在查詢參數中同時執行Id和UserId。 它可以節省sql服務器的負載,帶寬和網絡使用,因爲如果實體對登錄用戶無效,您不會返回任何不必要的數據。

插入:不會是一個問題,因爲無論如何您都需要將entity.UserId設置爲已登錄的用戶標識。

更新:這是您可能需要手動驗證entity.UserId是否與登錄用戶的ID相匹配的地方。但是,檢查EF是否有辦法「更新實體,其中Id = X和UserId = Y」 - 從長遠來看,這將使這種安全性更高,更容易維護。

Delete:與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語句來寫,只量。它也使得絕對不可能爲其他用戶獲取或刪除記錄。