2016-11-30 30 views
0

場景: (與ASP.NET web應用程序 - Core或MVC)ViewModel中的ASP.NET模型ID - 安全嗎?

我有UsersItems爲每個用戶的數據庫。 這意味着UserIdItems表中的foreign key

從瀏覽器我登錄爲User。我得到我的Items作爲ItemViewModels的列表,它們通過簡單的api GET請求映射(AutoMapper)到ItemViewModels

我想通過一個簡單的API調用更新其中一個項目(應屬於我 - 登錄的用戶)。因此,我通過PUT請求將修改的項目發送回服務器,作爲ItemViewModel

第一種方法:

最簡單的方法是將包括在ItemViewModel項目的數據庫ID,ItemId, - 所以當我收到被更新爲ItemViewModel的項目,我可以映射它回到數據庫中的現有項目。

這對我來說聽起來相當不安全,因爲任何人都可以用任何ItemId修改PUT請求並影響不屬於執行請求的用戶的項目。有什麼我錯過這種方法?

第二種方法:

不通過數據庫PK ItemIdItemViewModel。 請使用其他形式的標識:假設用戶X有10個項目。它們使用名爲UserItemId(它也存在於數據庫中)的屬性從1到10進行編號。

然後我就可以通過這個UserItemIdItemViewModel,當我拿回來我可以把它映射到數據庫中的現有項目(如果一切都ok了該請求),或者放棄它,並拒絕如果UserItemId沒要求不匹配登錄用戶項目中的任何內容。

有人使用這種方法嗎?

優點

用戶只能訪問它自己的項目,可以在不影響其他人的,因爲它不知道實際的項目ID(主鍵),以及任何修改都僅限於它的項目。

缺點

額外的管理大量必須在服務器端執行這種方法的工作。

還有其他方法嗎?

請考慮上面提到的情況適用於數據庫中客戶端實現可以CRUD的所有實體,所以它不僅僅是上面描述的簡單情況。

建議的解決方案應該適用於整個應用程序數據。

我知道這個問題已被問到herehere但第一個沒有令人滿意的答案,我不認爲第二個真的適用於我的情況,因爲它只是處理UserId。

謝謝。

EDIT

請考慮上述Item爲包含各多個複雜subItems與在db一個表中的聚合根。這個問題同樣適用於主要的Item。這意味着每個subItem都作爲ViewModel傳遞給客戶端。

我應該指出,關於進一步將更新請求:

  1. 對於第一種方法,如果允許用戶更改的項目,我可以很容易地檢查。但我也應該爲此做所有subItems

  2. 對於第二種方法,我可以檢查用戶是否可以更新Item如下:我獲得進入視圖模型的userItemId - >我得到的所有記錄在從數據庫用戶的項目,並試圖找到一個匹配同樣userItemId,如果我得到一個命中,然後我繼續更新。

+0

絕不信任用戶輸入。您必須**總是**在服務器上進行驗證。檢查當前用戶是否有權根據其ID來更新對象,並且只有當它們具有時才執行更新(否則重定向到錯誤頁面) –

回答

0

我認爲你的應用程序不安全,如果你只隱藏了Id。 在更改數據庫實體之前,您必須檢查是否允許用戶更改實體。 在你的情況下,你應該檢查,如果Id來自經過驗證的用戶是UserId在您的項目。 如果您的ViewModel與您的API相似或相同,您可以在控制器中使用FilterAttribute。

+0

感謝您的答覆。請參閱我的編輯。 – sevG