2015-09-07 44 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访问规则的细节。