我们有一些前端逻辑,使用选民来检查用户是否可以显示文档。应该在后端应用相同的逻辑,不同之处在于管理员用户是TokenStorage
中的活动用户。
if (false === $this->authorizationChecker->isGranted('show', $document)) {
continue;
}
应该使用相同的选民,但使用另一个用户对象(文档的所有者)。找不到有关临时更改选民身份验证用户的任何文档。
虽然the authorization docs mention setToken
,我无法想象覆盖令牌将是要走的路。那么,我们可以使用Symfony服务对我们自己的用户进行投票吗?一个目前尚未在TokenStorage
中活跃的(还)?
对于RoleVoter
后代,您可以交换存储的令牌并在检查权限后恢复它:
$tokenStorage = $this->get('security.token_storage');
$authorizationChecker = $this->get('security.authorization_checker');
// gets the user owner of the document
$owner = $document->getOwner();
// create new token for owner user/roles
$ownerToken = new AnonymousToken(null, $owner, $owner->getRoles());
// save current token to restore later
$prevToken = $tokenStorage->getToken();
// change the current token
$tokenStorage->setToken($ownerToken);
// checking now the owner roles
if ($authorizationChecker->isGranted('show', $document)) {
// ...
}
// restore the previous token
$tokenStorage->setToken($prevToken);
这些更改仅影响此时的访问决策。为了可重用,您可以创建一个新的AuthorizationChecker / Service,以便在isGranted
方法的第三个参数中使用该用户,如下所示:
$user = $document->getOwner();
if ($this->get('my_authorization_checker')->isGranted('show', $document, $user)) {
// ...
}
此方法将首先检查是否提供了用户,如果是,则更改令牌,否则不执行任何操作并检查已记录的用户。
尝试制作另一个authorizationChecker服务
<service id="app.token_storage" class="Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage" />
<service id="app.authorization_checker" class="Symfony\Component\Security\Core\Authorization\AuthorizationChecker">
<argument type="service" id="app.token_storage"/>
<argument type="service" id="security.authentication.manager"/>
<argument type="service" id="security.access.decision_manager"/>
<argument>false</argument>
</service>
然后在控制器中
$this->get('security.token_storage')->setToken($yourTokenToBeChecked);
$this->get('security.authorization_checker')->isGranted('show', $document);