【问题标题】:Access check in ExtbaseExtbase 中的访问检查
【发布时间】:2015-09-07 10:23:49
【问题描述】:

我有一个琐碎的任务,但我不知道处理它的预期方式。 我有一个控制器:

public function getObjectAction($object) {}

而且我想确保,该操作仅在 $object->getOwner() === $loggedInUser 时才会执行

现在的问题是:这个检查应该是怎样的?

  1. 操作内部的简单 if() 条件,在访问冲突的情况下会抛出 Exception。我不喜欢这个解决方案,因为它会迫使我在每个需要这样检查的操作中添加这样的 if()。当然,我可以创建一些 Trait,执行此检查并从每个此类控制器操作中调用 ->checkAccess(),但对我来说仍然看起来很脏。

  2. 控制器参数验证器。似乎更可靠的解决方案,因为我有单独的类,只执行它应该执行的操作(验证访问权限)。但这真的是一种验证还是一种滥用?

  3. 一些基于信号的重型系统,在动作发出之前发送。

  4. 您的变体(也许,已经有一些 ObjectAccessCheck 类左右,我还不知道)。

Source form TYPO3 lists

【问题讨论】:

  • 将所有操作放入一个自己的前端插件中,并使用前端的普通用户限制来限制这些操作的范围(如果您愿意,也可以制作两个控制器)。

标签: oop model-view-controller typo3 extbase


【解决方案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();
    }
}

如果您的控制器中有不需要此检查的操作,您可能希望将其拆分为两个控制器,一个用于受保护的方法,一个用于非受保护的方法。

您还可以对每个动作使用魔法初始化*动作,例如在你的情况下:

public function initializeGetObjectAction()

【讨论】:

  • 我喜欢这个解决方案,因为它允许选择不应该执行访问检查的控制器和/或操作,还因为存在对 Responce 和所有其他控制器功能的访问.目前,我正在使用解决方案,在此处作为评论发布,但如果我至少需要您的解决方案优势中的某些内容,我会改用它。
【解决方案2】:

最后我决定选择第 3 项。当前的应用程序逻辑是这样的,任何在参数中包含 MyObject 的控制器都应该执行访问检查。

我的ext_localconf.php

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

\MyVendor\MyExt\Slot\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 访问规则的详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多