Використання виразів у контролі доступу безпеки

Дата оновлення перекладу 2022-12-22

Використання виразів у контролі доступу безпеки

See also

Найкращим рішенням для роботи зі складними правилами авторизації є використання Системи виборців.

На додаток до ролі типу ROLE_ADMIN, метод isGranted() також приймає обʼєкт Expression:

  • Attributes
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Controller/MyController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\Response;

class MyController extends AbstractController
{
    #[IsGranted(new Expression(
        '"ROLE_ADMIN" in role_names or (is_authenticated() and user.isSuperAdmin())'
    ))]
    public function index(): Response
    {
        // ...
    }
}

6.2

Атрибут #[IsGranted()] було представлено в Symfony 6.2.

У цьому прикладі, якщо поточний користувач має ROLE_ADMIN або якщо метод обʼєкта поточного користувача isSuperAdmin() повертає true, то доступ буде гарантовано (примітка: ваш обʼєкт Користувача може не мати методу isSuperAdmin(), цей метод було вигадано для цього прикладу).

Це використовує вираз, а ви можете більше дізнатися про синтаксис мови виразів, див. .

Всередині виразу у вас є доступ до декількох змінних:

user
Обʼєкт користувача (або рядок anon, якщо ви не аутентифіковані).
role_names
Масив ролей, які має користувач, з рядковим представленням. Цей масив включає в себе всі ролі надані не напряму через ієрархію ролей , але не включає атрибути IS_AUTHENTICATED_* (див. функції нижче).
object
Обʼєкт (якщо є), який передається в якості другого аргументу isGranted().
subject
Зберігає те ж значення, що і object, тому вони еквівалентні.
token
Обʼєкт токена.
trust_resolver
Обʼєкт AuthenticationTrustResolverInterface,: ви скоріш за все використовуватимете функції is_*(), описані нижче.

Крім того, у вас є доступ до наступних функцій всередині виразу:

is_authenticated()
Повертає true, якщо користувач аутентифікований через "запамʼятати мене" або "повністю" аутентифікований - тобто, повертає "true", якщо користувач знаходиться у системі.
is_remember_me()
Схоже, але не еквівалентно з IS_AUTHENTICATED_REMEMBERED, див. нижче.
is_fully_authenticated()
Схоже, але не евівалентно з IS_AUTHENTICATED_FULLY, див. нижче.
is_granted()
Перевіряє, чи є у користувача заданий дозвіл. Додатково приймає другий аргумент з обʼєктом, де перевіряється дозвіл. Еквівалентно використанню методу isGranted() з сервісу безпеки.

Функції 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 $authorizationChecker): Response
{
    $access1 = $authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED');

    $access2 = $authorizationChecker->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" лише якщо користувач увійшов в систему протягом цієї сесії (тобто, повнофункціональний).