Asp.net-Mvc

ASP.NET MVC:動作內的授權 - 建議的模式或者這是一種氣味?

  • May 22, 2009

我有一個在控制器和操作上使用授權屬性的 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");
    }
}

引用自:https://stackoverflow.com/questions/889619