Rolle vs Berechtigungsbasierte Zugriffskontrolle

44

Ich versuche den inhärenten Kompromiss zwischen Rollen und Berechtigungen zu verstehen, wenn es um die Zugriffssteuerung (Autorisierung) geht.

Beginnen wir mit einer vorgegebenen: In unserem System ist eine Berechtigung eine fein abgestimmte Zugriffseinheit (" Ressource X bearbeiten ", "Auf die Dashboard-Seite zugreifen " usw.). Eine Rolle ist eine Sammlung von 1+ Berechtigungen. Ein Benutzer kann 1 oder mehr Rollen haben. Alle diese Beziehungen (Benutzer, Rollen, Berechtigungen) werden in einer Datenbank gespeichert und können im laufenden Betrieb und nach Bedarf geändert werden.

Meine Bedenken:

(1) Was ist so "schlecht" daran, Rollen für die Zugriffskontrolle zu überprüfen? Welche Vorteile bringt es, stattdessen nach Berechtigungen zu suchen? Mit anderen Worten, was ist der Unterschied zwischen diesen beiden Ausschnitten unten:

if(SecurityUtils.hasRole(user)) {
    // Grant them access to a feature
}

// vs.
if(SecurityUtils.hasPermission(user)) {
    // Grant them access to a feature
}

Und:

(2) Welchen nützlichen Wert bieten Rollen in diesem Szenario überhaupt? Können wir Benutzern nicht einfach 1+ Berechtigungen direkt zuweisen? Welchen konkreten Wert der Abstraktion bieten Rollen (kann jemand konkrete Beispiele nennen)?

smeeb
quelle
2
Ein paar Punkte: (1) Ein einzelner Benutzer kann mehrere Rollen haben, (2) Sie möchten sich vielleicht mit ACL (Access Control Lists) befassen, z. Möglicherweise möchten Sie "Zugriff auf die Dashboard-Seite" nur einer Teilmenge von Dashboard-Seiten gewähren können (falls mehrere vorhanden sind).
Matthieu M.

Antworten:

62

(1) Was ist so "schlecht" daran, Rollen für die Zugriffskontrolle zu überprüfen? Welche Vorteile bringt es, stattdessen nach Berechtigungen zu suchen?

Zum Zeitpunkt der Überprüfung muss der aufrufende Code nur wissen, ob Benutzer X die Berechtigung hat, Aktion Y auszuführen. .
Der aufrufende Code kümmert sich nicht darum und sollte die Beziehungen zwischen Rollen und Berechtigungen nicht kennen.

Die Berechtigungsschicht prüft dann, ob der Benutzer über diese Berechtigung verfügt, in der Regel, indem überprüft wird, ob die Rolle des Benutzers über diese Berechtigung verfügt. Auf diese Weise können Sie die Berechtigungslogik ändern, ohne den aufrufenden Code zu aktualisieren.

Wenn Sie direkt am Anrufstandort nach Rollen suchen, bilden Sie implizit Rollen-Berechtigungsbeziehungen und fügen dem aufrufenden Code Berechtigungslogik hinzu, wodurch die Trennung von Bedenken verletzt wird.

Sollten Sie später entscheiden, dass die Rolle fookeine Berechtigung haben soll baz, müssen Sie jeden Code ändern, der prüft, ob der Benutzer ein Benutzer ist foo.

(2) Welchen nützlichen Wert bieten Rollen in diesem Szenario überhaupt? Können wir Benutzern nicht einfach 1+ Berechtigungen direkt zuweisen? Welchen konkreten Wert der Abstraktion bieten Rollen (kann jemand konkrete Beispiele nennen)?

Rollen repräsentieren konzeptionell eine benannte Sammlung von Berechtigungen.

Angenommen, Sie fügen eine neue Funktion hinzu, mit der ein Benutzer bestimmte Einstellungen bearbeiten kann. Diese Funktion sollte nur für Administratoren verfügbar sein.

Wenn Sie Berechtigungen pro Benutzer speichern, müssen Sie alle Benutzer in Ihrer Datenbank suchen, von denen Sie irgendwie wissen, dass sie Administratoren sind (Wenn Sie keine Rolleninformationen für Benutzer speichern, woher wissen Sie dann überhaupt, welche Benutzer Administratoren sind?) Und anhängen diese Berechtigung zu ihrer Liste von Berechtigungen.

Wenn Sie Rollen verwenden, müssen Sie nur die Berechtigung an die AdministratorRolle anhängen. Dies ist einfacher durchzuführen, platzsparender und weniger fehleranfällig.

Rotem
quelle
Äh? Die Authentifizierungsschicht prüft, ob der Benutzer derjenige ist, der vorgibt zu sein. Die Schicht, die prüft, auf welche Funktionen / Daten ein solcher Benutzer zugreifen kann, ist die Berechtigungsschicht
SJuan76 13.10.15
4
Dies sollte für alle Programmierer obligatorisch sein. Ausgezeichnet.
Kosta Kontos
2
Einfach, prägnant und auf den Punkt gebracht - schlägt irgendwo ein ganzes Kapitel eines Buches. Vielen Dank.
Dan Nissenbaum
2
Kommentar zur Klarheit (und bitte korrigieren Sie mich, wenn ich mich irre): authorization layerWahrscheinlich bedeutet nichts anderes als einfach die Definition der Funktion zu haben (dh) user->hasPermission(SOME_PERMISSION)zuerst die Rollen des Benutzers intern zu überprüfen und dann zu überprüfen, ob eine der Rollen die angegebene Rolle einschließt / ausschließt Genehmigung. Beispielsweise the calling codekönnte geprüft werden, ob eine bestimmte Seite für den Benutzer sichtbar ist und aufgerufen werden würde user->hasPermission(VIEW_GIVEN_PAGE), und die authorization layerbesteht aus der Definition der hasPermissionFunktion, die die Rollen wie oben überprüft.
Dan Nissenbaum
1
@DanNissenbaum Ja, das hört sich so an, als ob Sie es richtig verstanden haben. Es kann so einfach sein, nur zu überprüfen, ob die Benutzerrolle diese Berechtigung besitzt. Es könnte auch mehr sein. Beispielsweise haben Sie möglicherweise die Möglichkeit, einen Benutzer vorübergehend zu sperren und in diesem Fall zu hasPermissionüberprüfen usersRole.HasPermission(VIEW_GIVEN_PAGE) && !user.Suspended. Der Punkt ist, dass alles an einem Ort erledigt wird und nicht im aufrufenden Code.
Rotem
18

Bei der Beantwortung Ihrer ersten Frage besteht das größte Problem bei der Überprüfung, ob ein Benutzer eine Rolle anstelle einer bestimmten Berechtigung hat, darin, dass Berechtigungen von mehreren Rollen gehalten werden können. Beispielsweise kann ein Entwickler Zugriff auf das Entwicklerportal im Unternehmensintranet haben, bei dem es sich wahrscheinlich auch um eine Berechtigung des Managers handelt. Wenn ein Benutzer dann versucht, auf das Entwicklerportal zuzugreifen, wird eine Überprüfung durchgeführt, die der folgenden ähnelt:

if(SecurityUtils.hasRole(developer)) {
    // Grant them access to a feature
} else if(SecurityUtils.hasRole(manager)) {
    // Grant them access to a feature
} else if...

(Eine switchAussage in der Sprache Ihrer Wahl wäre besser, aber nicht besonders aufgeräumt)

Je häufiger oder weit verbreiteter eine Berechtigung ist, desto mehr Benutzerrollen müssten Sie prüfen, um sicherzustellen, dass jemand auf ein bestimmtes System zugreifen kann. Dies würde auch zu dem Problem führen, dass Sie jedes Mal, wenn Sie Berechtigungen für eine Rolle ändern, die Prüfung ändern müssen, um dies widerzuspiegeln. In einem großen System würde dies sehr schnell sehr unhandlich werden.

Wenn Sie einfach überprüfen, ob der Benutzer über die Berechtigung verfügt, die ihm beispielsweise den Zugriff auf das Entwicklerportal ermöglicht, spielt es keine Rolle, welche Rolle er innehat, sondern er erhält Zugriff.

Der Grund für die Beantwortung Ihrer zweiten Frage ist, dass Rollen so einfach zu ändern und "Pakete" von Berechtigungen zu verteilen sind. Wenn Sie über ein System mit Hunderten von Rollen und Tausenden von Berechtigungen verfügen, müssen Sie zum Hinzufügen eines neuen Benutzers (z. B. eines neuen Personalleiters) alle Berechtigungen anderer Personalleiter erteilen. Dies wäre nicht nur mühsam, sondern auch fehleranfällig, wenn es manuell durchgeführt wird. Vergleichen Sie dies, indem Sie einem Benutzerprofil einfach die Rolle "HR-Manager" hinzufügen, wodurch ihm derselbe Zugriff gewährt wird wie jedem anderen Benutzer mit dieser Rolle.

Sie könnten argumentieren, dass Sie einfach einen vorhandenen Benutzer klonen könnten (wenn Ihr System dies unterstützt), aber während dies dem Benutzer die richtigen Berechtigungen für diesen Moment gewährt, könnte der Versuch, eine Berechtigung für alle Benutzer in der Zukunft hinzuzufügen oder zu entfernen, erfolgreich sein schwierig. Ein Beispielszenario hierfür wäre, wenn in der Vergangenheit möglicherweise auch die Personalabteilung für die Personalabrechnung zuständig war, das Unternehmen aber später groß genug wird, um Mitarbeiter speziell für die Personalabrechnung einzustellen. Das bedeutet, dass die Personalabteilung nicht mehr auf das Abrechnungssystem zugreifen muss, sodass die Berechtigung entfernt werden kann. Wenn Sie 10 verschiedene HR-Mitglieder haben, müssen Sie manuell durchgehen und sicherstellen, dass Sie die richtige Berechtigung entfernen, die die Möglichkeit von Benutzerfehlern einführt. Das andere Problem dabei ist, dass es einfach nicht skaliert; Wenn Sie mehr Benutzer für eine bestimmte Rolle gewinnen, wird das Ändern einer Rolle sehr viel schwieriger. Vergleichen Sie dies mit der Verwendung von Rollen, bei denen Sie nur die betreffende übergeordnete Rolle ändern müssen, um die Berechtigung zu entfernen. Dies würde sich für jeden Benutzer widerspiegeln, der diese Rolle innehat.

Matt Champion
quelle
gutes Beispiel, danke!
Frank