Étape 15: Sécuriser l’interface d’administration
Sécuriser l’interface d’administration¶
L’interface d’administration ne doit être accessible que par des personnes autorisées. La sécurisation de cette zone du site peut se faire à l’aide du composant Symfony Security.
Comme pour Twig, le composant de sécurité est déjà installé par des dépendances transitives. Ajoutons-le explicitement au fichier composer.json
du projet :
1 | $ symfony composer req security
|
Définir une entité User¶
Même si les internautes ne pourront pas créer leur propre compte sur le site, nous allons créer un système d’authentification entièrement fonctionnel pour l’admin. Nous n’aurons donc qu’un seul User, l’admin du site.
La première étape consiste à définir une entité User
. Pour éviter toute confusion, nommons-la plutôt Admin
.
Pour utiliser l’entité Admin
dans le système d’authentification de Symfony, celle-ci doit respecter certaines exigences spécifiques. Par exemple, elle a besoin d’une propriété password
.
Utilisez la commande dédiée make:user
pour créer l’entité Admin
au lieu de la commande traditionnelle make:entity
:
1 | $ symfony console make:user Admin
|
Répondez aux questions qui vous sont posées : nous voulons utiliser Doctrine pour stocker nos users (yes
), utiliser username
pour le nom d’affichage unique des admins et chaque admin aura un mot de passe (yes
).
La classe générée contient des méthodes comme getRoles()
, eraseCredentials()
et d’autres qui sont nécessaires au système d’authentification de Symfony.
Si vous voulez ajouter d’autres propriétés à l’entité Admin
, exécutez make:entity
.
Ajoutons une méthode __toString()
comme EasyAdmin les aime :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | --- a/src/Entity/Admin.php
+++ b/src/Entity/Admin.php
@@ -75,6 +75,11 @@ class Admin implements UserInterface
return $this;
}
+ public function __toString(): string
+ {
+ return $this->username;
+ }
+
/**
* @see UserInterface
*/
|
En plus de générer l’entité Admin
, la commande a également mis à jour la configuration de sécurité pour connecter l’entité au système d’authentification :
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
@@ -1,7 +1,15 @@
security:
+ encoders:
+ App\Entity\Admin:
+ algorithm: auto
+
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
- 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)/
|
Nous laissons Symfony choisir le meilleur algorithme possible pour encoder les mots de passe (il évoluera avec le temps).
Il est temps de générer une migration et de migrer la base de données :
1 2 | $ symfony console make:migration
$ symfony console doctrine:migrations:migrate -n
|
Générer un mot de passe pour l’admin¶
Nous ne développerons pas de système dédié pour créer des comptes d’administration. Encore une fois, nous n’aurons qu’un seul admin. Le login sera admin
et nous devons encoder le mot de passe.
Choisissez ce que vous voulez comme mot de passe et exécutez la commande suivante pour générer le mot de passe encodé :
1 | $ symfony console security:encode-password
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Symfony Password Encoder Utility
================================
Type in your password to be encoded:
>
------------------ ---------------------------------------------------------------------------------------------------
Key Value
------------------ ---------------------------------------------------------------------------------------------------
Encoder used Symfony\Component\Security\Core\Encoder\MigratingPasswordEncoder
Encoded password $argon2id$v=19$m=65536,t=4,p=1$BQG+jovPcunctc30xG5PxQ$TiGbx451NKdo+g9vLtfkMy4KjASKSOcnNxjij4gTX1s
------------------ ---------------------------------------------------------------------------------------------------
! [NOTE] Self-salting encoder used: the encoder generated its own built-in salt.
[OK] Password encoding succeeded
|
Créer un admininistrateur¶
Insérez l’admin grâce à une requête 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')"
|
Notez l’échappement du caractère $
dans le mot de passe ; échappez tous les caractères qui en ont besoin !
Configurer le système d’authentification¶
Maintenant que nous avons un admin, nous pouvons sécuriser l’interface d’administration. Symfony accepte plusieurs stratégies d’authentification. Utilisons un classique système d’authentification par formulaire.
Exécutez la commande make:auth
pour mettre à jour la configuration de sécurité, générer un template pour la connexion et créer une classe d’authentification (authenticator) :
1 | $ symfony console make:auth
|
Sélectionnez 1
pour générer une classe d’authentification pour le formulaire de connexion, nommez la classe d’authentification AppAuthenticator
, le contrôleur SecurityController
et créez une URL /logout
(yes
).
La commande a mis à jour la configuration de sécurité pour lier les classes générées :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | --- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -16,6 +16,13 @@ security:
security: false
main:
anonymous: lazy
+ guard:
+ authenticators:
+ - App\Security\AppAuthenticator
+ 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#firewalls-authentication
|
Comme l’indique la sortie de la commande, nous devons personnaliser la route dans la méthode onAuthenticationSuccess()
pour rediriger l’admin lorsqu’il a réussi à se connecter :
1 2 3 4 5 6 7 8 9 10 11 12 | --- a/src/Security/AppAuthenticator.php
+++ b/src/Security/AppAuthenticator.php
@@ -96,8 +96,7 @@ class AppAuthenticator extends AbstractFormLoginAuthenticator implements Passwor
return new RedirectResponse($targetPath);
}
- // For example : return new RedirectResponse($this->urlGenerator->generate('some_route'));
- throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
+ return new RedirectResponse($this->urlGenerator->generate('easyadmin'));
}
protected function getLoginUrl()
|
Astuce
Comment puis-je savoir que la route d’EasyAdmin est easyadmin
? Je ne peux pas. Mais j’ai lancé la commande suivante qui montre l’association entre les noms de route et les chemins :
1 | $ symfony console debug:router
|
Ajouter les règles de contrôle d’accès¶
Un système de sécurité se compose de deux parties : l”authentification et l”autorisation. Lors de la création de l’admin, nous lui avons donné le rôle ROLE_ADMIN
. Limitons la section /admin
aux seules personnes ayant ce rôle en ajoutant une règle à access_control
:
1 2 3 4 5 6 7 8 9 | --- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -34,5 +34,5 @@ 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 }
|
Les règles access_control
limitent l’accès par des expressions régulières. Lorsqu’une personne connectée tente d’accéder à une URL qui commence par /admin
, le système de sécurité vérifie qu’elle a bien le rôle ROLE_ADMIN
.
S’authentifier avec le formulaire de connexion¶
Si vous essayez d’accéder à l’interface d’administration, vous devriez maintenant être redirigé vers la page de connexion et être invité à entrer un identifiant et un mot de passe :

Connectez-vous en utilisant admin
et le mot de passe que vous avez encodé précédemment. Si vous avez copié exactement ma requête SQL, le mot de passe est admin
.
Notez qu’EasyAdmin s’intègre automatiquement au système d’authentification de Symfony :

Essayez de cliquer sur le lien « Sign out ». Et voilà ! Nous avons une interface d’administration entièrement sécurisée.
Note
Si vous voulez créer un système complet d’authentification par formulaire, jetez un coup d’œil à la commande make:registration-form
.
- « Previous Étape 14: Accepter des commentaires avec les formulaires
- Next » Étape 16: Empêcher le spam avec une API
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.