Extbase 中的访问检查
Access check in Extbase
我有一项琐碎的任务,但我不知道处理它的预期方式。
我有一个控制器:
public function getObjectAction($object) {}
而且我想确保只有在 $object->getOwner() === $loggedInUser
时才会执行该操作
现在的问题是:这张支票应该是怎样的?
动作内部的简单 if() 条件,在发生访问冲突时抛出 Exception。我不喜欢这个解决方案,因为它会迫使我在每个需要这样检查的动作中添加这样一个 if() 。当然,我可以创建一些特征,执行此检查并从每个这样的控制器操作调用 ->checkAccess()
,但它对我来说仍然看起来很脏。
控制器参数验证器。似乎是更可靠的解决方案,因为我有单独的 class,它只执行它应该执行的操作(验证访问权限)。但这真的是验证还是误用?
一些重系统,基于信号,在动作发出之前发送。
您的变体(也许,已经有一些 ObjectAccessCheck class 左右,我还不知道)。
方案一很简单,你可以把它弄脏一点。
假设你想对控制器中的每个动作执行检查,你可以只使用 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()
最后我决定选择第 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
);
}
}
}
}
}
该方案的缺点:slot 为任何动作运行,可能会占用一些资源。
好处:控制器不应该知道有关 MyObject 访问规则的详细信息。
我有一项琐碎的任务,但我不知道处理它的预期方式。 我有一个控制器:
public function getObjectAction($object) {}
而且我想确保只有在 $object->getOwner() === $loggedInUser
现在的问题是:这张支票应该是怎样的?
动作内部的简单 if() 条件,在发生访问冲突时抛出 Exception。我不喜欢这个解决方案,因为它会迫使我在每个需要这样检查的动作中添加这样一个 if() 。当然,我可以创建一些特征,执行此检查并从每个这样的控制器操作调用
->checkAccess()
,但它对我来说仍然看起来很脏。控制器参数验证器。似乎是更可靠的解决方案,因为我有单独的 class,它只执行它应该执行的操作(验证访问权限)。但这真的是验证还是误用?
一些重系统,基于信号,在动作发出之前发送。
您的变体(也许,已经有一些 ObjectAccessCheck class 左右,我还不知道)。
方案一很简单,你可以把它弄脏一点。
假设你想对控制器中的每个动作执行检查,你可以只使用 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()
最后我决定选择第 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
);
}
}
}
}
}
该方案的缺点:slot 为任何动作运行,可能会占用一些资源。
好处:控制器不应该知道有关 MyObject 访问规则的详细信息。