2015-09-07 71 views
0

我有一個簡單的任務,但我不知道處理它的預期方式。 我有一個控制器:訪問檢查Extbase

public function getObjectAction($object) {} 

而且我希望確保,這一行動將執行只有$object->getOwner() === $loggedInUser

現在的問題:如何檢查應該是什麼?的動作,其拋出異常訪問衝突的情況下,內部

  1. 簡單如果()的條件。我不喜歡這個解決方案,因爲它會迫使我在每個動作中添加這樣一個if(),需要這樣的檢查。當然,我可以創建一些Trait,執行此檢查,並從每個此類控制器操作中調用->checkAccess(),但對我來說仍然很髒。

  2. 控制器參數驗證器。似乎更可靠的解決方案,因爲我有單獨的類,它只執行它應該執行的操作(驗證訪問權限)。但是,這真的是一個驗證或濫用?

  3. 一些沉重的系統,根據信號,發出行動之前發送或等。

  4. 您的變體(也許,已經有一些ObjectAccessCheck類,或者我還沒有意識到)。

Source form TYPO3 lists

+0

將所有操作放入自己的前端插件中,並使用前端的普通用戶限制來限制這些操作的範圍(如果需要,也可以製作兩個控制器)。 – pgampe

回答

1

解決方案1是非常簡單的,你可以把它一點點不太髒。

假設你要執行的檢查在控制器的每一個動作,你可以只使用initializeAction

public function initializeAction() { 
    if (!$this->myObjectService->isAuthenticatedUserOwnerOfObject($this->arguments['myObject'])) { 
     $code = 401; 
     $message = 'Authorization Required'; 
     $this->response->setStatus($code, $message); 
     $this->response->shutdown(); 
    } 
} 

如果你在你的控制器不需要此檢查的行爲,你可能想將其分爲兩個控制器,一個用於保護,一個用於非保護方法。

您還可以對每個動作使用magic initialize *動作,例如你的情況:

public function initializeGetObjectAction() 
+0

我喜歡這個解決方案,因爲它允許選擇控制器和/或動作,這些控制器和/或動作不應該執行訪問檢查,也可以訪問* Responce *和所有其他控制器功能。目前,我正在使用解決方案,在此處發佈評論,但如果我至少需要解決方案優勢中的某些內容,我會切換到該解決方案。 –

0

最後我決定去項目3.當前應用程序的邏輯是這樣的,任何控制器,它具有爲MyObject在爭論應該執行訪問檢查。

ext_localconf.php

$signalSlotDispatcher->connect(
    \TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, 
    'beforeCallActionMethod', 
    \MyVendor\MyExt\Slot\MyObjectAccessor::class, 
    'actionAuthorized' 
); 

\的Myvendor \ MyExt \這個解決方案的槽\ MyObjectAccessor

class MyObjectAccessor{ 

    use LoggedInUserAccessor; 

    /** 
    * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface 
    * @inject 
    */ 
    protected $objectManager; 

    /** 
    * Checks whether current user is allowed to access MyObject, from provided arguments 
    * @param string $controller 
    * @param string $action 
    * @param array $arguments 
    * @throws AccessViolationException 
    */ 
    public function actionAuthorized($controller, $action, array $arguments) { 
     foreach($arguments as $argument) { 
      // if MyObject is accessed and it was persisted before 
      if(($argument instanceof MyObject) && $argument->getUid()) { 
       $loggedInUser = $this->getLoggedInUser(); 
       if($argument->getUser() !== $loggedInUser) { 
        throw new AccessViolationException(
         'Access violation by "' . $loggedInUser->getUsername() . '" with MyObject "' . $argument->getTitle() . '"', 
         1441808407 
        ); 
       } 
      } 
     } 
    } 
} 

缺點:插槽任何操作運行,它可以吃一些資源。

好處:沒有控制器應該知道關於MyObject訪問規則的細節。