Heute morgen ist mir aufgefallen, dass eine Seite, für die ich eigentlich Zugriffsrechte gebraucht hätte, mir alles offenbarte. Schuld wäre der automatische Verfall des Token, so dachte ich. Immerhin war der PC über Nacht eingeschaltet. Beim erneuten Testen der Access Control habe ich dann noch andere „lustige“ Bugs gefunden…
Access Control ist nicht wasserdicht!
Symfony bietet eine Sektion in der config.yml
, in der ganze Bereiche der fertige Seite mit Zugriffsbeschränkungen versehen werden kann. Die Einrichtung erfolgt recht schnell und kann beliebig viele Einträge umfassen.
security: # ... access-control: - { path: ^/admin, role: ROLE_ADMIN } - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
So gesehen ist die Funktion sehr komfortabel, lässt aber massive Lücken zu! Controller, die keine echte Response zurückgeben (sondern z.B. einen Download auslösen) werden hierbei nicht beschränkt! Zwar wird im HTML ein Fehler angezeigt, wenn man die Seite aufruft, trotzdem startet der Download im Hintergrund. Das ist sehr schlecht, wenn man eine Route zum Export der Datenbank als CSV bereitstellt…
Wie sollte man es lösen?
Nun ist die access_control
Sektion zum Glück nicht die einzige Möglichkeit, den Benutzer zu überprüfen. Die Security-Komponente erlaubt nämlich auch das direkte Überprüfen von Rollen in einem Controller. Ein existierende Funktion bzw. der ganze Controller mit all seinen Funktionen kann mit einer Annotation beschränkt werden:
/** * Class LicenceController * @Route("/admin") * @Security("has_role('ROLE_ADMIN')") */ class AdminController extends Controller { //... }
PS: Keine Beschränkung für erneuten Login?
Ein Feature, das Symfony noch fehlt, ist die Beschränkung für bereits erfolgte Logins. Geht man als angemeldeter Benutzer zurück auf die Login-Seite geschieht nichts! Vorteilhaft wäre hier ein Verbot oder eine Umleitung auf eine andere Seite. Leider lässt sich dies nirgends ausführen…
Hinzu kommt, dass jeder angemeldete Nutzer zusätzlich zur Rolle das Flag IS_AUTHENTICATED_ANONYMOUSLY
trägt, sich also auch nicht von nicht-identifizierten Nutzern unterscheiden lässt. Wer den Schwachsinn programmiert hat gehört gekreuzigt!!! Folgende Einstellung zeigt somit auch keine Wirkung:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
Eine ordentlich Lösung gibt es hierfür leider auch (noch) nicht. Theoretisch könnte man das mit einer Expression der Form not IS_AUTHENTICATED_FULLY
lösen, das bleibt aber vorerst Theorie…
Schreibe einen Kommentar