Як створювати та включати користувацькі перевірки користувача

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

Як створювати та включати користувацькі перевірки користувача

Під час аутентифікації користувача можуть знадобитися додаткові перевірки для верифікації того, чи дозволено користувачу виконати вхід. Визначивши користувацьку перевірку користувача, ви можете визначити, яку перевірку використовувати для кожного брандмауера.

Створення користувацької превірки користувача

Перевірки користувача - це класи, які повинні реалізовувати UserCheckerInterface. Цей інтерфейс визначає два методи під назвами checkPreAuth() і checkPostAuth() для виконання перевірок до та після аутентифікації користувача. Якщо не дотримується одна чи більше умов, має бути викликано виключення, яке розширює AccountStatusException. Розгляньте використанння CustomUserMessageAccountStatusException, який розширює AccountStatusException та дозволяє налаштувати повідомлення помилки, відображене користувачу:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
namespace App\Security;

use App\Entity\User as AppUser;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class UserChecker implements UserCheckerInterface
{
    public function checkPreAuth(UserInterface $user): void
    {
        if (!$user instanceof AppUser) {
            return;
        }

        if ($user->isDeleted()) {
            // повідомлення, передане цьому виключенню, призначено для відображення користувачу
            throw new CustomUserMessageAccountStatusException('Your user account no longer exists.');
        }
    }

    public function checkPostAuth(UserInterface $user): void
    {
        if (!$user instanceof AppUser) {
            return;
        }

        // в акаунту користувача завершився строк дії, можна сповістити користувача
        if ($user->isExpired()) {
            throw new AccountExpiredException('...');
        }
    }
}

Включення користувацької перевірки користувача

Далі, переконайтеся в тому, що ваша перевірка користувача зареєстрована як сервіс. Якщо ви використовуєте конфігурацію services.yml за замовчуванням , то сервіс реєструється автоматично.

Все, що залишається зробити, - це додати перевірку до бажаного брандмауера, де значенням буде id сервісу вашої перевірки:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
# config/packages/security.yaml

# ...
security:
    firewalls:
        main:
            pattern: ^/
            user_checker: App\Security\UserChecker
            # ...

Використання декількох перевірок користувача

6.2

Клас ChainUserChecker було додано у Symfony 6.2.

Для додатків розповсджено мати багато точок входу аутентифікації (таких як традиційна форма входу у систему та API), які можуть мати унікальни правила перевірок для кожної точки входу, а також спільні правила для всіх точок входу. Щоб дозволити використання багатьох перевірок користувача у брандмауері, створюється сервіс для класу ChainUserChecker для кожного брандмауера.

Щоб використати ланцюгову перевірку користувача, спочатку, вам знадобиться тегувати ваші сервіси перевірки користувача тегом security.user_checker.<firewall> (де <firewall> - імʼя брандмауера у вашій конфігурації безпеки). Тег сервісу також підтримує атрибут пріоритету, що дозволяє вам визначати порядок, в якому викликаються ваші перевірки:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
# config/services.yaml

# ...
services:
    App\Security\AccountEnabledUserChecker:
        tags:
            - { name: security.user_checker.api, priority: 10 }
            - { name: security.user_checker.main, priority: 10 }

    App\Security\APIAccessAllowedUserChecker:
        tags:
            - { name: security.user_checker.api, priority: 5 }

Як тільки ваші сервіси перевірок будуть теговані, далі, вам потрібно буде сконфігурувати ваші брандмауери, щоб вони використовували сервіс security.user_checker.chain.<firewall>:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
# config/packages/security.yaml

# ...
security:
    firewalls:
        api:
            pattern: ^/api
            user_checker: security.user_checker.chain.api
            # ...
        main:
            pattern: ^/
            user_checker: security.user_checker.chain.main
            # ...