Безопасность: Сложный контроль доступа с выражениями

Наилучшим решением для работы со сложными правилами авторизации является использование Системы избирателей.

В дополнение к роли вроде ROLE_ADMIN, метод isGranted() также принимает объект Expression:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
use Symfony\Component\ExpressionLanguage\Expression;
// ...

public function index()
{
    $this->denyAccessUnlessGranted(new Expression(
        '"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())'
    ));

    // ...
}

В этом примере, если текущий пользователь имеет ROLE_ADMIN или если метод объекта текущего пользователя isSuperAdmin() возвращает true, то доступ будет гарантирован (примечание: ваш объект Пользователь может не иметь метода isSuperAdmin(), этот метод был выдуман для данного примера).

Используется выражение, и вы можете узнать больше о синтаксисе языка выражений, см. The Expression Syntax.

Внутри выражения у вас есть доступ к нескольким переменным:

user
Объект пользователя (или строка anon, если вы не аутентифицированы).
roles
Массив ролей, которые имеет пользователь, включая роли из иерархии ролей, но не включая атрибуты IS_AUTHENTICATED_* (см. функции ниже).
object
Объект (если есть), которые передаётся в качестве второго аргумента isGranted().
token
Объект токена.
trust_resolver
Объект AuthenticationTrustResolverInterface,: вы скорее всего будете использовать функции is_*(), описанные ниже.

Кроме того, у вас есть доступ к следующим функциям внутри выражения:

is_authenticated
Возвращает true, если пользователь аутентифицирован через "запомнить меня" или "полностью" аутентифицирован - т.е. возвращает "true", если пользователь находится в системе.
is_anonymous
Эквивалентно использованию IS_AUTHENTICATED_ANONYMOUSLY с функуцией isGranted().
is_remember_me
Похоже на, но не эквивалентно IS_AUTHENTICATED_REMEMBERED, см. ниже.
is_fully_authenticated
Похоже, но не эквивалентно IS_AUTHENTICATED_FULLY, см. ниже.
has_role
Проверяет, имеет ли пользователь заданную роль - эквиваленно выражению вроде 'ROLE_ADMIN' in roles.

Функции is_remember_me() и is_authenticated_fully() похожи на использование IS_AUTHENTICATED_REMEMBERED и IS_AUTHENTICATED_FULLY с функцией isGranted(), но они не одинаковы. Следующий отрезок из контроллера демонстрирует отличия:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
// ...

public function index(AuthorizationCheckerInterface $auth)
{
    $access1 = $auth->isGranted('IS_AUTHENTICATED_REMEMBERED');

    $access2 = $auth->isGranted(new Expression(
        'is_remember_me() or is_fully_authenticated()'
    ));
}

Здесь, $access1 и $access2 будут иметь одинаковое значение. В отличие от поведения IS_AUTHENTICATED_REMEMBERED и IS_AUTHENTICATED_FULLY, функция is_remember_me() возвращает "ture" только, если пользователь аутентифицирован через куки "запомнить меня" и is_fully_authenticated, возвращает "true" только, если пользователь вошел в систему в течение этой сессии (т.е. полнофункциональный).

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.