Защита административной панели
Административная панель должна быть доступна только доверенным лицам. Защитить её можно с помощью компонента Symfony Security.
Определение сущности пользователя
Несмотря на то, что посетители не смогут создавать учётные записи на сайте самостоятельно, мы создадим полнофункциональную систему аутентификации для администратора. Поэтому у нас будет только один пользователь — администратор сайта.
На первом шаге давайте определим сущность User. Чтобы избежать возможной путаницы, назовём её Admin.
Для интеграции сущности Admin с системой аутентификации Symfony Security, она должна соответствовать определённым требованиям. Например, наличие свойства password является обязательным.
Для создания сущности Admin выполните специальную команду make:user вместо обычной make:entity.
1
$ symfony console make:user Admin
Ответьте на вопросы в терминале: использовать ли Doctrine для хранения администраторов (yes), какое из свойств использовать для отображения имени администратора (username), должен ли каждый пользователь иметь пароль (yes).
Созданный класс содержит методы вроде getRoles(), eraseCredentials() и многие другие, необходимые Symfony для системы аутентификации.
Используйте команду make:entity, если вам нужно добавить дополнительные свойства в сущность Admin.
Помимо создания самой сущности Admin, команда также обновит конфигурацию безопасности и свяжет сущность с системой аутентификации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
--- i/config/packages/security.yaml
+++ w/config/packages/security.yaml
@@ -5,14 +5,18 @@ security:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
- users_in_memory: { memory: null }
+ # used to reload user from session & other features (e.g. switch_user)
+ app_user_provider:
+ entity:
+ class: App\Entity\Admin
+ property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
- provider: users_in_memory
+ provider: app_user_provider
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
Выбор наилучшего алгоритма для хеширования паролей (который со временем будет меняться) мы оставим на усмотрение Symfony.
Пришло время создать миграцию и применить её к базе данных:
1 2
$ symfony console make:migration
$ symfony console doctrine:migrations:migrate -n
Создание пароля для администратора
Так как у нас будет всего лишь один администратор, мы не будем разрабатывать отдельную систему для создания администраторских учётных записей. В качестве логина используем admin и захешируем пароль.
Придумайте любой пароль и при помощи следующей команды захешируйте его:
1
$ symfony console security:hash-password
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Symfony Password Hash Utility
=============================
Type in your password to be hashed:
>
------------------ ---------------------------------------------------------------------------------------------------
Key Value
------------------ ---------------------------------------------------------------------------------------------------
Hasher used Symfony\Component\PasswordHasher\Hasher\MigratingPasswordHasher
Password hash $argon2id$v=19$m=65536,t=4,p=1$BQG+jovPcunctc30xG5PxQ$TiGbx451NKdo+g9vLtfkMy4KjASKSOcnNxjij4gTX1s
------------------ ---------------------------------------------------------------------------------------------------
! [NOTE] Self-salting hasher used: the hasher generated its own built-in salt.
[OK] Password hashing succeeded
Создание администратора
Добавьте администратора, используя следующий SQL-запрос:
1 2 3
$ symfony run psql -c "INSERT INTO admin (id, username, roles, password) \
VALUES (nextval('admin_id_seq'), 'admin', '[\"ROLE_ADMIN\"]', \
'\$argon2id\$v=19\$m=65536,t=4,p=1\$BQG+jovPcunctc30xG5PxQ\$TiGbx451NKdo+g9vLtfkMy4KjASKSOcnNxjij4gTX1s')"
Обратите внимание на экранирование знака $ в столбце пароля; экранируйте их все!
Настройка аутентификации
Теперь, когда у нас есть пользователь с правами администратора, мы можем защитить административную панель. Symfony поддерживает несколько стратегий аутентификации. Давайте воспользуемся классической и достаточно популярной системой аутентификации с помощью формы.
Команда make:security:form-login обновит конфигурацию безопасности, сгенерирует шаблон с формой входа, а также создаст аутентификатор (класс для управления аутентификацией):
1
$ symfony console make:security:form-login
Назовите контроллер SecurityController и ответьте yes, чтобы добавить маршрут для выхода из системы по пути /logout.
Для связывания вновь созданных классов, команда обновит настройки безопасности:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
--- i/config/packages/security.yaml
+++ w/config/packages/security.yaml
@@ -15,7 +15,15 @@ security:
security: false
main:
lazy: true
- provider: users_in_memory
+ provider: app_user_provider
+ form_login:
+ login_path: app_login
+ check_path: app_login
+ enable_csrf: true
+ logout:
+ path: app_logout
+ # where to redirect after logout
+ # target: app_any_route
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
Tip
Помню ли я, что маршрутом к EasyAdmin является admin (который задан в App\Controller\Admin\DashboardController)? Вряд ли. Эту информацию можно получить из файла класса или по следующей команде, отображающей все имеющиеся маршруты и соответсвующие пути:
1
$ symfony console debug:router
Добавление правил контроля доступа для авторизации
Система безопасности состоит из двух частей: аутентификация и авторизация . При создании администратора мы добавили ему роль ROLE_ADMIN. Чтобы ограничить доступ к разделу /admin только для пользователей имеющих эту роль, необходимо добавить правило в access_control:
1 2 3 4 5 6 7 8 9 10 11
--- i/config/packages/security.yaml
+++ w/config/packages/security.yaml
@@ -34,7 +34,7 @@ security:
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- # - { path: ^/admin, roles: ROLE_ADMIN }
+ - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
when@test:
Правила access_control ограничивают доступ с помощью регулярных выражений. При переходе по URL-адресу, который начинается с /admin, система безопасности проверит наличие роли ROLE_ADMIN у авторизованного пользователя.
Аутентификация через форму входа
Теперь при открытии административной панели вы автоматически окажетесь на странице входа, где вам будет предложено ввести логин и пароль:
Войдите в систему, используя логин admin и незашифрованный пароль, который был захеширован вами ранее. Если вы корректно скопировали мою SQL-команду, то пароль будет admin.
Обратите внимание, что EasyAdmin автоматически распознает систему аутентификации Symfony:
Попробуйте нажать на ссылку "Sign out". Всё готово! Теперь у вас есть полностью защищённая административная панель.
Note
Если вы хотите создать полноценную систему аутентификации с использованием формы, используйте команду make:registration-form.