Das Admin-Backend absichern
Die Admin-Backend-Schnittstelle sollte nur für vertrauenswürdige Personen zugänglich sein. Die Sicherung dieses Bereichs der Website kann mit der Symfony Security-Komponente erfolgen.
Eine User Entity definieren
Auch wenn die Teilnehmerinnen nicht in der Lage sein werden, ihre eigenen Konten auf der Website zu erstellen, werden wir ein voll funktionsfähiges Authentifizierungssystem für einen Administratorin einrichten. Wir werden daher nur einen einzigen Benutzerin haben.
Der erste Schritt ist die Definition einer User
-Entity. Um Verwechslungen zu vermeiden, benennen wir sie stattdessen Admin
.
Um die Admin
-Entity im Authentifizierungssystem von Symfony Security zu integrieren, muss sie einige spezifische Anforderungen erfüllen. Zum Beispiel benötigt sie ein password
-Feld.
Verwende den make:user
-Befehl anstatt dem üblichen make::entity
-Befehl, um die Admin
-Entity zu erstellen:
1
$ symfony console make:user Admin
Beantworte die interaktiven Fragen: Wir wollen Doctrine verwenden, um die Admins zu speichern (yes
), verwende username
für den eindeutigen Anzeigenamen von Admins, und jeder Benutzerin wird ein Passwort haben (yes
).
Die generierte Klasse enthält Methoden wie getRoles()
, eraseCredentials()
, und ein paar andere, die vom Symfony-Authentifizierungssystem benötigt werden.
Falls Du demr Admin
-Benutzerin weitere Eigenschaften hinzufügen möchtest, verwende make:entity
.
Lass uns noch eine __toString()
-Methode hinzufügen, weil EasyAdmin diese gerne benutzt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
--- a/src/Entity/Admin.php
+++ b/src/Entity/Admin.php
@@ -54,6 +54,11 @@ class Admin implements UserInterface, PasswordAuthenticatedUserInterface
return (string) $this->username;
}
+ public function __toString(): string
+ {
+ return $this->username;
+ }
+
/**
* @see UserInterface
*/
Zusätzlich zum Erzeugen der Admin
-Entity aktualisierte der Befehl auch die Sicherheitskonfiguration, um die Entity mit dem Authentifizierungssystem zu verbinden:
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
Wir lassen Symfony den besten verfügbaren Algorithmus zum Hashen von Passwörtern auswählen (diese werden sich im Laufe der Zeit weiterentwickeln).
Zeit, eine Migration zu generieren und die Datenbank zu migrieren:
1 2
$ symfony console make:migration
$ symfony console doctrine:migrations:migrate -n
Ein Passwort für dieen Admin-Benutzerin generieren
Wir werden kein spezielles System zur Erstellung von Admin-Konten entwickeln. Auch hier werden wir immer nur einen Admin haben. Das Login wird admin
sein und wir müssen den Passwort-Hash generieren.
Wähle App\Entity\Admin
mit einem beliebigen Passwort und führe den folgenden Befehl aus, um den Passwort-Hash zu generieren:
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
Einen Administratorin erstellen
Füge dieen Admin-Benutzerin über einen SQL-Befehl hinzu:
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')"
Siehst Du, wie das $
-Zeichen in unserem Wert in der Passwortspalte escaped wurde? Escapen nie vergessen!
Die Sicherheits-Authentifizierung konfigurieren
Jetzt, da wir einen Admin-Benutzerin haben, können wir das Admin-Backend absichern. Symfony unterstützt mehrere Authentifizierungsstrategien. Lass uns ein klassisches und verbreitetes Formular-Authentifizierungssystem verwenden.
Führe den make:auth
-Befehl aus, um die Sicherheitskonfiguration zu aktualisieren, ein Login-Template zu generieren und einen Authentifikator zu erstellen.
1
$ symfony console make:auth
Wähle 1
, um einen Login-Formular-Authentifikator zu generieren, benenne die Authentifikatorklasse AppAuthenticator
, den Controller SecurityController
und generiere eine /logout
-URL (yes
).
Der Befehl hat die Sicherheitskonfiguration aktualisiert, um die generierten Klassen zu verbinden:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
--- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -17,6 +17,11 @@ security:
main:
lazy: true
provider: app_user_provider
+ custom_authenticator: 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#the-firewall
Wie von der Befehlsausgabe angedeutet, müssen wir die Route in der onAuthenticationSuccess()
-Methode anpassen, um Benutzer*innen nach erfolgreicher Anmeldung umzuleiten:
1 2 3 4 5 6 7 8 9 10 11 12 13
--- a/src/Security/AppAuthenticator.php
+++ b/src/Security/AppAuthenticator.php
@@ -49,9 +49,7 @@ class AppAuthenticator extends AbstractLoginFormAuthenticator
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('admin'));
}
protected function getLoginUrl(Request $request): string
Tip
Wie merke ich mir, dass die EasyAdmin-Route (wie in App\Controller\Admin\DashboardController
konfiguriert) admin
ist? Gar nicht. Du kannst in die Datei schauen, oder aber auch den folgenden Befehl ausführen, der die Zuordnung zwischen Routennamen und Pfaden anzeigt:
1
$ symfony console debug:router
Berechtigungsregeln für die Zugriffskontrolle hinzufügen
Ein Sicherheitssystem besteht aus zwei Teilen: Authentifizierung und Autorisierung. Beim Erstellen desr Admin-Benutzersin haben wir ihmr die ROLE_ADMIN
-Rolle gegeben. Wir schränken den /admin
-Bereich auf Benutzerinnen mit dieser Rolle ein, indem wir eine Regel zu access_control
hinzufügen:
1 2 3 4 5 6 7 8 9 10 11
--- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -32,7 +32,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:
Die access_control
-Regeln schränken den Zugriff durch reguläre Ausdrücke ein. Beim Versuch, auf eine URL zuzugreifen, die mit /admin
beginnt, überprüft das Sicherheitssystem, dass die angemeldeten Benutzer*innen die ROLE_ADMIN
-Rolle besitzen.
Über das Login-Formular authentifizieren
Wenn Du versuchst, auf das Admin-Backend zuzugreifen, solltest Du nun auf die Login-Seite weitergeleitet und aufgefordert werden, einen Usernamen und ein Passwort einzugeben:
Melde Dich mit admin
und dem Klartext-Passwort an, das Du zuvor als Hash gewählt hast. Wenn Du meinen SQL-Befehl genau kopiert hast, lautet das Passwort admin
.
Beachte, dass EasyAdmin das Symfony-Authentifizierungssystem automatisch erkennt:
Versuche, auf den Link "Abmelden" zu klicken. Und fertig! Ein vollständig gesicherter Backend-Adminbereich.
Note
Wenn Du ein vollwertiges Formular-Authentifizierungssystem erstellen möchtest, wirf einen Blick auf den make:registration-form
-Befehl.