[英]MVC C#: Authenticating current user has rights to view/update data
我們公司目前正在將我們的軟件從 Web 表單重新制作為 MVC,並且在我們將其發布給我們的客戶之前,它目前處於 alpha 階段。 簡而言之,該應用程序有多家酒店訂閱和使用我們的服務。 我現在需要確保的核心安全是沒有用戶應該能夠訪問/修改屬於另一家酒店的數據。
我們的模型大多遵循以下兩個示例之一:
RoomCategory (structure: model.HotelID)
--------------
ID
HotelID
Room (structure: model.Parent.HotelID)
--------------
ID
RoomCategoryID
HotelID
問題是,當我在 ~/rooms/edit/1 上時,我可以將表單操作 URL 和隱藏字段值從“1”更改為“50”,並且房間 ID 50 屬於另一家酒店。 這是一個大問題,因為一個用戶實際上可以從另一家酒店“竊取”一個房間並將其變成自己的房間! 我們的客戶不會很高興。
我處理問題的方式...
從當前登錄的用戶數據(從會話訪問),我們知道用戶有權管理的酒店(或酒店)。 一種方法是驗證每個動作調用並執行如下操作:
app.AuthenticateAccess(room.RoomCategory.HotelID);
這樣,AuthenticateAccess 函數將阻止進一步操作並“重定向”到 Unauthorized/NotFound 頁面,因為它知道 Room ID 50 屬於 HotelID 2 而當前用戶無權訪問它。 當然,我認為這是一種安全的方法,但這涉及每個控制器中所有操作的大量重復函數調用。
我一直在尋找在全球范圍內克服這一安全挑戰的不同可能性:
我有一些其他的解決方案,比如使用 System.Reflection 搜索所有 HotelID 屬性並確保允許當前用戶創建所有保存/創建的數據。 但無論如何,讓我聽聽您解決這個問題的方法,因為我還不相信我能想到的任何解決方案。
永遠不要相信來自客戶端的數據。 在對數據庫進行任何更新/交易之前,始終驗證發布的數據。
因此,在您的 HttpPost 操作方法中,您在繼續之前運行清理檢查
[HttpPost]
public ActionResult Book(BookingViewModel model)
{
var isGood = hotelService.DoesCurrentUserHasAccessToRoom(model.RoomId);
if(isGood)
{
//Continue with Saving
hotelService.BookRoom(model);
return RedirectToAction("BookingCompleted");
}
return View("NotAuthorized");
}
只要您根據需要將它們放入服務中的小型可重用方法中,就不會有重復的代碼。
其他選項是添加 HMAC 字段來檢查敏感數據(隱藏 id 字段)是否未更改,我使用過一次就再也沒有使用過,過度解決方案。
話雖如此...
我多次遇到相同的問題,我想過幾乎相同的選項,從長遠來看,我堅持使用最簡單的解決方案 GetById 存儲庫方法傳遞CurrentUserId
,例如:
Entity GetById(int id, int? userId);
為什么?
您要求的是粒度級別的授權,只有在您知道操作中涉及的確切記錄時才能獲得,那么為什么不首先在負責獲取記錄的方法中進行檢查呢?
如果記錄存在並且用戶創建了該記錄,則返回該記錄,否則返回 null,因為該用戶不存在該對象,甚至不必費心返回“您不擁有該對象”類型的消息,只是一個普通的和簡單的 404“記錄不存在”。
如果您願意,您可以嘗試使用相同的方法,但使用ActionFilters
,類似於此。 但是您必須弄清楚如何在該過濾器上下文中檢索記錄。
對於具有完全訪問權限的管理員,如果您將 null 傳遞給該方法,您可以繞過該檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.