Метод voteOnAttribute класса Voter
Метод voteOnAttribute класса Voter вызывается
после метода supports и принимает решение о доступе.
Первым параметром передаётся атрибут (обычно строка),
вторым - объект субъекта (например, сущность),
третьим - токен аутентификации.
Метод должен вернуть true, если доступ разрешён,
или false - если запрещён.
Синтаксис
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
Пример
Давайте создадим voter, который разрешает редактирование статьи только её автору. Сначала проверим, что пользователь авторизован:
<?php
namespace AppSecurity;
use AppEntityArticle;
use AppEntityUser;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityCoreAuthorizationVoterVoter;
class ArticleVoter extends Voter
{
const EDIT = 'edit';
protected function supports(string $attribute, mixed $subject): bool
{
return $attribute === self::EDIT && $subject instanceof Article;
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
/** @var Article $article */
$article = $subject;
return $article->getAuthor() === $user;
}
}
?>
Пример
Давайте проверим доступ в контроллере с помощью метода isGranted:
<?php
namespace AppController;
use AppEntityArticle;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
use SymfonyComponentSecurityHttpAttributeIsGranted;
class ArticleController extends AbstractController
{
#[Route('/article/{id}/edit', name: 'article_edit')]
#[IsGranted('edit', subject: 'article')]
public function edit(Article $article): Response
{
return new Response('"article ' . $article->getId() . ' edited"');
}
}
?>
Результат выполнения кода для автора статьи:
"article 1 edited"
Результат выполнения кода для другого пользователя:
403 Access Denied
Пример
Давайте добавим проверку роли администратора в метод voteOnAttribute:
<?php
namespace AppSecurity;
use AppEntityArticle;
use AppEntityUser;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityCoreAuthorizationVoterVoter;
class ArticleVoter extends Voter
{
const EDIT = 'edit';
protected function supports(string $attribute, mixed $subject): bool
{
return $attribute === self::EDIT && $subject instanceof Article;
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
if (in_array('ROLE_ADMIN', $user->getRoles())) {
return true;
}
/** @var Article $article */
$article = $subject;
return $article->getAuthor() === $user;
}
}
?>