Skip to content

Защита административной панели

Административная панель должна быть доступна только доверенным лицам. Защитить её можно с помощью компонента 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
--- a/config/packages/security.yaml
+++ b/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
--- a/config/packages/security.yaml
+++ b/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
--- a/config/packages/security.yaml
+++ b/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 у авторизованного пользователя.

Аутентификация через форму входа

Теперь при открытии административной панели вы автоматически окажетесь на странице входа, где вам будет предложено ввести логин и пароль:

/login/

Войдите в систему, используя логин admin и незашифрованный пароль, который был захеширован вами ранее. Если вы корректно скопировали мою SQL-команду, то пароль будет admin.

Обратите внимание, что EasyAdmin автоматически распознает систему аутентификации Symfony:

/admin/

Попробуйте нажать на ссылку "Sign out". Всё готово! Теперь у вас есть полностью защищённая административная панель.

Note

Если вы хотите создать полноценную систему аутентификации с использованием формы, используйте команду make:registration-form.

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.
TOC
    Version