Schritt 15: Das Admin-Backend absichern
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.
Wie bei Twig ist die Sicherheitskomponente bereits über transitive Abhängigkeiten installiert. Fügen wir sie explizit zur composer.json
-Projektdatei hinzu:
1 | $ symfony composer req security
|
Eine User Entity definieren¶
Auch wenn die Teilnehmer*innen nicht in der Lage sein werden, ihre eigenen Konten auf der Website zu erstellen, werden wir ein voll funktionsfähiges Authentifizierungssystem für eine*n Administrator*in einrichten. Wir werden daher nur eine*n einzige*n Benutzer*in 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 jede*r Benutzer*in 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 dem*r Admin
-Benutzer*in weitere Eigenschaften hinzufügen möchtest, verwende make:entity
.
Lass uns noch eine __toString()
-Methode hinzu, 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
@@ -75,6 +75,11 @@ class Admin implements UserInterface
return $this;
}
+ 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 | --- 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)/
|
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 die*en Admin-Benutzer*in 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 vom Passwort speichern wir nur den Hashwert.
Wähle ein beliebiges Passwort und führe den folgenden Befehl aus, um den Passwort-Hash zu generieren:
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
|
Eine*n Administrator*in erstellen¶
Füge die*en Admin-Benutzer*in ü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 eine*n Admin-Benutzer*in 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 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
|
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 | --- 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()
|
Tipp
Woher weiß ich, dass die EasyAdmin-Route easyadmin
heißt? Ich weiß es nicht. Aber ich habe den folgenden Befehl ausgeführt, 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 des*r Admin-Benutzers*in haben wir ihm*r die ROLE_ADMIN
-Rolle gegeben. Wir schränken den /admin
-Bereich auf Benutzer*innen mit dieser Rolle ein, indem wir eine Regel zu access_control
hinzufügen:
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 }
|
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 gespeichert 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.
Bemerkung
Wenn Du ein vollwertiges Formular-Authentifizierungssystem erstellen möchtest, wirf einen Blick auf den make:registration-form
-Befehl.
- « Previous Schritt 14: Feedback mit Formularen annehmen
- Next » Schritt 16: Spam mit Hilfe einer API verhindern
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.