Hier gibt es viele Fragen, die sich mit den Mechanismen der Authentifizierung und Autorisierung von RESTful-APIs befassen, aber keine von ihnen scheint Einzelheiten zur Implementierung sicherer Dienste auf Anwendungsebene zu enthalten.
Angenommen, meine Webanwendung (ich habe Java im Sinn, dies gilt jedoch für jedes Backend) verfügt über ein sicheres Authentifizierungssystem, mit dem sich Benutzer der API mit einem Benutzernamen und einem Kennwort anmelden können. Wenn der Benutzer eine Anfrage stellt, kann ich zu jedem Zeitpunkt während der Pipeline für die Anforderungsverarbeitung eine getAuthenticatedUser()
Methode aufrufen , die entweder den Nullbenutzer zurückgibt, wenn der Benutzer nicht angemeldet ist, oder ein Benutzerdomänenobjekt, das den angemeldeten Benutzer darstellt.
Die API ermöglicht authentifizierten Benutzern den Zugriff auf ihre Daten, z. B. ein GET, /api/orders/
um die Auftragsliste dieses Benutzers zurückzugeben. In ähnlicher Weise gibt ein GET to /api/tasks/{task_id}
Daten zurück, die sich auf diese bestimmte Aufgabe beziehen.
Nehmen wir an, dass es eine Reihe verschiedener Domänenobjekte gibt, die einem Benutzerkonto zugeordnet werden können (Bestellungen und Aufgaben sind zwei Beispiele, wir könnten auch Kunden, Rechnungen usw. haben). Wir möchten nur, dass authentifizierte Benutzer auf Daten zu ihren eigenen Objekten zugreifen können. Wenn ein Benutzer einen Anruf tätigt, müssen /api/invoices/{invoice_id}
wir überprüfen, ob der Benutzer berechtigt ist, auf diese Ressource zuzugreifen, bevor wir sie bereitstellen.
Meine Frage ist dann, ob es Muster oder Strategien gibt, um dieses Autorisierungsproblem zu lösen. Eine Option, die ich in Betracht ziehe, ist das Erstellen einer Hilfsschnittstelle (dh SecurityUtils.isUserAuthorized(user, object)
), die während der Anforderungsverarbeitung aufgerufen werden kann, um sicherzustellen, dass der Benutzer zum Abrufen des Objekts berechtigt ist. Dies ist nicht ideal, da es den Anwendungsendpunktcode mit vielen dieser Aufrufe verschmutzt, z
Object someEndpoint(int objectId) {
if (!SecurityUtils.isUserAuthorized(loggedInUser, objectDAO.get(objectId)) {
throw new UnauthorizedException();
}
...
}
... und dann stellt sich die Frage, ob diese Methode für jeden Domänentyp implementiert werden kann, was ein bisschen schmerzhaft sein kann. Dies könnte die einzige Option sein, aber ich würde mich über Ihre Vorschläge freuen!