Dass sich eine Person anmelden kann, beweist nicht, dass sie berechtigt ist, sämtliche Daten der Anwendung aufzurufen oder zu ändern. Die Authentifizierung identifiziert den Benutzer; die Autorisierung entscheidet, was er mit welcher Ressource und unter welchen Bedingungen tun darf. Eine Route kann eine gültige Sitzung voraussetzen und dennoch jemandem erlauben, die Bestellung eines anderen Kontos zu lesen, wenn die Beziehung zwischen Benutzer und Ressource nicht geprüft wird.
Autorisierungstests in PHP sollten diese Grenze über die Einstiegspunkte prüfen, die die Anwendung verwendet: zum Beispiel eine HTTP-Anfrage an eine Webroute oder eine API. Ziel ist nicht, zu testen, wie ein Framework seine Richtlinien implementiert, sondern das beobachtbare Verhalten zu bestätigen: Wer darf was tun, wann wird eine Anfrage abgelehnt und welche Daten bleiben unverändert?
Zugriffsregeln in eine Matrix übertragen

Formulieren Sie die Regeln vor dem Schreiben der Tests anhand von vier Elementen: Akteur, Aktion, Ressource und Kontext. Zum Kontext gehören Bedingungen, die die Berechtigung beeinflussen, etwa die Zugehörigkeit zur selben Organisation, der Besitz des Datensatzes oder ein bestimmter Status. Diese Struktur verhindert, dass Autorisierung auf eine Rollenliste reduziert wird.
- Akteur: anonymer Benutzer, Mitglied, Verantwortlicher oder Administrator.
- Aktion: abrufen, erstellen, bearbeiten, löschen oder genehmigen.
- Ressource: eine Bestellung, ein Dokument, ein Konto oder ein anderes geschütztes Objekt.
- Kontext: Eigentümer, Organisation, Ressourcenstatus oder bestehende Beziehung.
Eine Regel kann beispielsweise vorsehen, dass ein Mitglied seine eigenen Bestellungen abrufen darf, während ein Verantwortlicher die Bestellungen seiner Organisation abrufen darf. Ein Administrator könnte weitergehenden Zugriff haben, vorbehaltlich der tatsächlichen Produktregeln. Die Matrix überführt jede Geschäftsanforderung in überprüfbare Fälle und macht fehlende Kombinationen sichtbar.
Es ist nicht nötig, alle denkbaren Permutationen zu testen. Priorisieren Sie Vertrauensgrenzen: einen Benutzer ohne Sitzung, zwei Benutzer derselben Organisation, Benutzer verschiedener Organisationen, eine Person mit einer privilegierten Rolle und eine Ressource, die ihr nicht gehört. Ergänzen Sie besondere Kontexte, die die Entscheidung ändern, etwa eine archivierte Bestellung, wenn dafür andere Berechtigungen gelten als für eine aktive.
Repräsentative Integrationsszenarien vorbereiten
Bereiten Sie die Daten explizit und in kleinem Umfang vor. Bei einem typischen Test können zwei Organisationen, je ein Benutzer pro Organisation und eine Ressource angelegt werden, die einer der Organisationen zugeordnet ist. Authentifizieren Sie anschließend den Benutzer, der auf die Ressource zugreifen möchte, und senden Sie eine Anfrage an die öffentliche Route der Anwendung, wobei Sie die Ressourcen-ID verwenden. So werden Einstiegspunkt, Authentifizierung, Autorisierung und Antwort gemeinsam geprüft.
Fügen Sie für jede wichtige Regel mindestens einen erlaubten und einen abgelehnten Fall hinzu. Wenn der Eigentümer eine Ressource bearbeiten darf, prüfen Sie, dass die autorisierte Bearbeitung funktioniert und ein anderer Benutzer sie nicht durchführen kann. Ein positiver Fall ist unverzichtbar: Eine Testsuite, die nur Ablehnungen erwartet, könnte auch dann bestehen, wenn die Anwendung auch berechtigte Benutzer blockiert.
Prüfen Sie außerdem eine nicht vorhandene Ressource. Die Antwort auf eine unbekannte ID kann sich von der Antwort auf eine vorhandene Ressource unterscheiden, für die keine Berechtigung besteht. Manche Anwendungen verwenden eine Antwort mit dem Status „Nicht gefunden“, um die Existenz der Ressource nicht offenzulegen; andere teilen mit, dass der Zugriff verboten ist. Der Test sollte die bewusst festgelegte Produktrichtlinie abbilden und keine allgemeingültige Konvention erzwingen.
Verwenden Sie Factories, Fixture-Builder oder Test-Helper, die gültige und gut lesbare Zustände erzeugen. Vermeiden Sie Abhängigkeiten von festen IDs, der Ausführungsreihenfolge oder gemeinsam genutzten Daten, die ein anderer Test ändern könnte. Wenn die Persistenz Teil des zu prüfenden Verhaltens ist, überprüfen Sie das Ergebnis mit den üblichen Projektwerkzeugen in der Datenbank; nehmen Sie nicht an, dass eine erfolgreiche Antwort allein den korrekten Zustand garantiert.
Die Isolation zwischen Benutzern und Organisationen testen
Die Isolation verdient eigene Testfälle, weil Fehler häufig auftreten, wenn eine ID in der URL oder im Anfrageinhalt geändert wird. Erstellen Sie eine Ressource für ein Konto und versuchen Sie, sie mit einer anderen Identität abzurufen, zu bearbeiten oder zu löschen. Wiederholen Sie die Prüfung zwischen Organisationen, wenn die Anwendung Datenbereiche pro Unternehmen hat. Testen Sie bei kritischen Vorgängen jede Aktion: Ein geschützter Lesezugriff beweist nicht, dass auch Download, Export oder Aktualisierung geschützt sind.
Um nicht die gesamte Testsuite zu duplizieren, teilen Sie die gemeinsame Vorbereitung und parametrisieren Sie nur die Dimensionen, die die Regel ausdrücken. Eine Liste von Akteur-Ressource-Paaren kann beispielsweise festlegen, welche Kombinationen zulässig sind. Behalten Sie aussagekräftige Namen für konkrete Fälle bei: „Mitglied einer anderen Organisation darf die Bestellung nicht bearbeiten“ erklärt mehr als eine undurchsichtige Menge boolescher Werte. Trennen Sie Szenarien, wenn sich Methode, Route oder erwartete Auswirkungen unterscheiden.
Vermeiden Sie es, jede Rollenkombination mit jeder Ressource zu testen, wenn viele davon keine unterschiedlichen Regeln abbilden. Ermitteln Sie stattdessen begründete Äquivalenzen und behalten Sie explizite Fälle für Ausnahmen und Grenzfälle bei. Wenn es hierarchische Rollen gibt, nehmen Sie nicht an, dass eine automatisch alle Berechtigungen einer anderen erbt: Prüfen Sie die tatsächlich für das Produkt geltende Regel.
Antworten und Nebeneffekte überprüfen
Prüfen Sie bei einer Ablehnung sowohl die Antwort als auch, dass der geschützte Vorgang nicht ausgeführt wurde. Je nach Schnittstelle kann die Antwort eine Weiterleitung, ein Status für nicht authentifizierten oder verbotenen Zugriff oder eine Antwort mit dem Status „Nicht gefunden“ sein. Prüfen Sie den relevanten Vertrag – Status, Format und gegebenenfalls Nachricht –, ohne den Test unnötig an Darstellungsdetails zu koppeln.
Prüfen Sie bei einer abgelehnten Aktualisierung, dass sensible Felder unverändert geblieben sind. Bei einer Löschung muss der Datensatz weiterhin verfügbar sein. Bei einem Vorgang, der eine Rechnung, eine Benachrichtigung oder ein Ereignis erzeugt, prüfen Sie auch, dass dieser Effekt nicht eingetreten ist. Die Assertions sollten geschäftlich wichtige Auswirkungen abdecken, nicht nur den HTTP-Statuscode.
Eine nicht autorisierte Anfrage darf auch keine partiellen Änderungen ermöglichen. Führt der Ablauf mehrere Vorgänge aus, prüfen Sie, dass die Ablehnung vor den Änderungen erfolgt oder dass die Transaktion das System in einem konsistenten Zustand belässt. Sie müssen dafür keine privaten Methoden untersuchen: Beobachten Sie die Antwort sowie die persistierten Daten oder Auswirkungen.
Tests widerstandsfähig gegenüber Implementierungsänderungen halten
Integrationstests sollten über eine stabile Schnittstelle der Anwendung laufen, etwa eine Route und eine Anfrage mit einer Identität, die über die verfügbaren Testmechanismen authentifiziert wurde. Rufen Sie nicht direkt eine interne Richtlinienklasse auf, wenn Sie den tatsächlichen Zugriff auf eine Ressource prüfen möchten: Dadurch könnten die Routeneinbindung, die Middleware oder die Art, wie das Objekt geladen wird, ungeprüft bleiben.
Machen Sie die Testsuite zugleich nicht zu einem Abbild der gesamten Anwendung. Prüfen Sie den Autorisierungsvertrag an repräsentativen Punkten und verwenden Sie Unit-Tests für reine Regeln, die viele Kontextfälle benötigen. Die Kombination erleichtert die Fehlersuche: Ein Regeltest kann eine Bedingung isoliert prüfen, während der Integrationstest bestätigt, dass diese Regel den bereitgestellten Ablauf schützt.
Wenn sich Rollen, Routen oder Richtlinien ändern, überprüfen Sie die Matrix, bevor Sie Erwartungen anpassen. Ein Test, der lediglich aktualisiert wird, um das neue Ergebnis zu akzeptieren, kann eine versehentliche Ausweitung von Berechtigungen verschleiern. Dokumentieren Sie, warum sich die Regel geändert hat, ermitteln Sie, welche Akteure Zugriff erhalten oder verlieren, und ergänzen Sie Fälle, die die neuen Grenzen schützen.
Checkliste zur Überprüfung einer Änderung

- Sind Akteur, Aktion, Ressource und Kontext definiert?
- Gibt es für die betroffene Regel mindestens ein erlaubtes und ein abgelehntes Szenario?
- Wird der Zugriff zwischen Benutzern oder Datenbereichen geprüft, sofern relevant?
- Werden eine nicht vorhandene Ressource und die gewählte Richtlinie zum Schutz vor der Offenlegung von Informationen abgedeckt?
- Läuft die Anfrage über den Einstiegspunkt, der geschützt werden muss?
- Wird geprüft, dass eine Ablehnung weder Daten ändert noch Nebeneffekte erzeugt?
- Sind die Testdaten isoliert, gut lesbar und reproduzierbar?
- Entsprechen die Erwartungen einer Produktentscheidung und keinem zufälligen Detail des Frameworks?
Eine nützliche Testsuite beweist nicht abstrakt, dass „Berechtigungen vorhanden sind“: Sie zeigt, dass die relevanten Kombinationen funktionieren und nicht autorisierte Kombinationen die Grenze nicht überschreiten. Eine solche Matrix zusammen mit konkreten Integrationstests erleichtert die Überprüfung von Änderungen am Zugriff, ohne die Sicherheit an eine bestimmte interne Implementierung zu binden.



