ASP.NET MVC:動作內的授權 - 建議的模式或者這是一種氣味?
我有一個在控制器和操作上使用授權屬性的 ASP.NET MVC 應用程序。這一直運作良好,但出現了新的皺紋。
對象:裝運
角色:運輸、會計、一般使用者
貨件通過工作流程移動。在狀態 A 中,它只能由 Shipping 編輯。在狀態 B 中,它只能由會計編輯。
我有一個 ShipmentController 和一個 Edit Action。我可以放置一個 Authorization 屬性來將 Edit 操作限制為僅這兩個角色,但這並不能區分 Shipment 處於哪個狀態。我需要在服務呼叫之前在操作中執行一些 Authorization 以確定使用者是否真正被授權執行編輯操作。
所以我有兩個問題:
1)在Action中獲得授權的好方法是什麼。Controller Action 呼叫服務,然後服務對 Shipment 對象進行適當的呼叫(更新數量、更新日期等)。我確定我希望 Shipment 對像不受任何授權要求的影響。另一方面,如果我希望服務對象知道授權,我並沒有真正的把握。有什麼好的模式嗎?
2)我的問題實際上是糟糕設計的症狀嗎?我應該有一個 StateAshipmentController 和 StateBshipmentController,而不是 ShipmentController?我沒有在 Shipment 對像中內置任何多態性(狀態只是一個列舉),但也許我應該並且控制器應該反映這一點。
我想我正在尋求更通用的解決方案,而不是針對我的案例的特定解決方案。我只是想提供一個例子來說明這個問題。
謝謝!
您的授權屬性可以從操作參數或路線數據中獲取貨件,然後做出決定。
對於第 1 點,有許多模式可以在域對像中啟用豐富的行為。在雙重分派中,您將對服務抽象(介面)的引用傳遞給對像上的方法。然後它可以做它的事情。您還可以編寫一個應用程序服務來接收 Shipment 並完成工作。
2號,不一定。您可能需要將“上下文 Shipment”的概念抽象為一項服務,以確定您所處的 Shipment 上下文。但在您再次需要它之前,我會使用 YAGNI。
我認為 Action 方法在其中進行進一步的授權檢查沒有問題。您可以利用角色提供程序來獲得您正在尋找的細粒度授權。請原諒我的語法 - 它可能很粗糙,我還沒有測試過。
[Authorize(Roles="Shipping, Accounting")] public ActionResult Edit(int id) { Shipment shipment = repos.GetShipment(id); switch (shipment.State) { case ShipmentState.A: if (Roles.IsUserInRole("Shipping")) return View(shipment); else return View("NotAuthorized"); break; case ShipmentState.B: if (Roles.IsUserInRole("Accounting")) return View(shipment); else return View("NotAuthorized"); break; default: return View("NotAuthorized"); } }