Новое в Symfony 5.1: Обновленная система безопасности

Symfony 5.1 будет включать новую систему безопасности как одну из самых больших новых функций. После нескольких месяцев планирования, обсуждений и тяжелой работы смогли вовремя завершить работу над Symfony 5.1 в качестве экспериментальной функции.

Основные отличия от предыдущей системы:

Убрано все кроме гвардии

В новой системе безопасности есть только один слушатель, который передает запрос диспетчеру аутентификатора, предоставленному Symfony. Этот менеджер заботится об управлении сеансом, хранении токена, функции «Запомнить меня» и т. д.

Все связано с единой концепцией и интерфейсом: аутентификаторами. Это упрощает внутреннюю структуру компонента безопасности и упрощает понимание разработчиками.

2. Перешли на систему, основанную на событиях

Компонент безопасности не использовал события Symfony для расширения всех своих возможностей. Новая система меняет это, и она основана на трех событиях:

  • CheckPassportEvent, это главное событие, которое проверяет действительность указанных учетных данных (пароль, сертификат, токен CSRF и т. д.)
  • LoginSuccessEvent, отправляемое, когда учетные данные действительны.
  • LoginFailureEvent, отправляется, когда учетные данные неверны.

Вот и все! Три простых события дают вам всю гибкость, необходимую вашим приложениям.

3. Охранники нового поколения

Охранники были введены в Symfony 2.8 через GuardAuthenticatorInterface. Новая система безопасности позволяет упростить некоторые функции Guard и улучшить другие. Для начала, метод checkCredentials() удален, а методы getCredentials() и getUser() были объединены в метод, называемый authenticate().

Это вводит несколько новых концепций:

  • Passport, метод authenticate() возвращает «паспорт безопасности», который содержит объект пользователя и все учетные данные, необходимые для его аутентификации;
  • Бейджи, дополнительная информация, необходимая для паспорта.

Паспорта и значки используются слушателями CheckPassportEvent, которые проверяют паспорт и все его значки. Если все значки разрешены, пользователь успешно аутентифицирован.

Вот упрощенный пример работы новой системы при использовании в форме входа:

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;

class FormAuthenticator implements AuthenticatorInterface
{
    // ...

    public function authenticate(Request $request): PassportInterface
    {
        // find a user based on an "email" form field
        $user = $this->userRepository->findOneByEmail($request->get('email'));
        if (!$user) {
            throw new UsernameNotFoundException();
        }

        return new Passport($user, new PasswordCredentials($request->get('password')), [
            // and CSRF protection using a "csrf_token" field
            new CsrfTokenBadge('loginform', $request->get('csrf_token')),

            // and add support for upgrading the password hash
            new PasswordUpgradeBadge($request->get('password'), $this->userRepository)
        ]);
    }
}

Новая система безопасности по умолчанию отключена, но вы можете включить ее следующим образом:

# config/packages/security.yaml
security:
    # ...
    enable_authenticator_manager: true