Zugangskontrollen
Mit Zugangskontrollen (ACL) kann das System fein granular gesteuert werden, welche Aspekte ein User im System ausführen/benutzen darf.
Eine ACL besteht aus 4 Komponenten: Die Art (Typ) der ACL, die abgedeckten Operationen, die betroffene Resource sowie ein Level (ein Subset an Daten aus der Resource).
Jede ACL verfügt über eine Liste an Rollen sowie eine Bedingung. Diese kann optional einen Datensatz erhalten für die Prüfung. Um die ACL zu erfüllen und somit dem Benutzer die eingestellte Operation zu gestatten, muss der User
- Eine der Rollen haben (ist keine Rolle eingetragen ist dies automatisch erfüllt)
- UND die Bedienung muss erfüllt sein (falls vorhanden)
Typen
Entity
Eine Entity ACL beschreibt, was ein User mit einem Datensatz machen kann. Es gibt hier die Operationen Lesen, Erstellen, Aktualisieren, Löschen, Global Search und Suchen.
Die Resource ist eine Entity Art und das Level beschränkt die ACL auf ein Feld der gewählten Entity.
Wichtig: Die Ergebnisse für ein user.can(ACTION, ENTITY, ...)
, das client-seitig abgefragt wird, werden einmalig server-seitig berechnet.
Client-seitige Berechtigungsabfragen sind bspw. dafür zuständig verschiedene Knöpfe auszuschalten, falls es die Businesslogik so erfordert.
Aus Sicherheitsgründen werden diese Prüfungen schlussendlich auch auf dem Server geprüft.
Damit lassen sich nun folgende Berechtigungen konstruieren:
1. Resource ist befüllt und Level ist leer:
Eine ACL mit einem leeren Level bezieht sich immer auf einen Datensatz als Ganzes.
Lesen:
Darf der User einen bestimmten Datensatz der definierten Resource lesen.
Verhalten auf Listen:
- falls ein Datensatz für die Lesen ACL ein "false" zurückliefert, werden alle Felder des Datensatzes als Sensitive angezeigt
- sensitive Datensätze können nicht aus der Liste geöffnet werden
- für die Bedingung der Lesen ACL stehen alle Felder des Datensatzes zur Verfügung, unabhängig von den gewählten selectFields der Query
Verhalten auf Layout:
- falls der Datensatz durch einen Link direkt geöffnet wird, wird der User auf die allgemeine 403 Forbidden Fehlermeldung weitergeleitet
Verhalten in GlobalSearch:
- die Lesen ACL wird für die gefundenen Datensätze der GlobalSearch geprüft, falls ein "false" zurückgeliefert wird, wird der betroffene Datensatz herausgefiltert und dem User nicht zurückgeliefert
- hier sind aus technischen Beschränkungen zurzeit nur die Felder aus der ViewToField Tabelle der GlobalSearch View zur Verfügung
Erstellen & Aktualisieren:
Darf der User einen Datensatz des definierten Ressourcentypen neu anlegen bzw. aktualisieren.
Verhalten:
- falls ein einziger neuer Datensatz erstellt oder aktualisiert wird und der ACL-Check "false" zurückliefert, wird ein generischer "Not allowed" Fehler geschmissen
- falls mehrere Datensätze erstellt oder aktualisiert werden, wird für jeden Datensatz ein ACL-Check durchgeführt, falls für einen dieser Datensätze ein "false" zurückgeliefert wird, wird dieser aus der Liste herausgefiltert
Verhalten auf Layout:
- abhängig vom persisted-Flag wird das Layout anhand der Erstellen oder Aktualisieren ACL readonly geschaltet
Verhalten in Related Lists: Im Speziellen geht es hier nun um den Edit und den Create Button der Related Lists. Falls eine der unten stehenden ACL's "false" zurückliefert, wird der jeweilige Button ausgeblendet.
- OneToMany Relation:
- der Edit Button prüft die Aktualisieren ACL der Zieltabelle
- der Create Button prüft die Erstellen ACL der Zieltabelle
- ManyToMany Relation:
- der Edit Button prüft die Erstellen ACL der Zwischentabelle
- der Create Button prüft die Erstellen ACL der Zwischentabelle und der Zieltabelle
Löschen:
Darf der User einen Datensatz des definierten Ressourcentypen löschen.
Verhalten:
- falls ein einziger Datensatz gelöscht wird und der ACL-Check "false" zurückliefert, wird dieser Datensatz nicht gelöscht
- falls mehrere Datensätze gelöscht werden und der ACL-Check "false" zurückliefert, wird dieser Datensatz aus der Liste an zu löschenden Datensätzen herausgefiltert
Suchen:
Schränkt die Query auf Listen für den gegebenen Ressourcentypen weiter ein.
Verhalten:
- es wird zuerst die Bedingung der Suchen ACL geprüft, falls diese einen "true" zurückliefert, wird die darunter angegebene Query auf die Query der Liste angewendet
- gibt es mehrere wahre Suchen ACL's werden die Queries jeweils mit einer ODER Gruppe verknüpft
- Wichtig: hier steht kein "record" zur Verfügung, sondern nur der User!
Global Search:
Darf der User Datensätze des Ressourcentypen in der GlobalSearch finden
Verhalten:
- falls eine GlobalSearch ACL ein "true" zurückliefert, wird die Resource mit in die GlobalSearch aufgenommen
- Wichtig: hier steht ebenfalls kein "record" zur Verfügung, sondern nur der User!
2. Resource ist befüllt und Level ist *:
Eine ACL mit dem Level * bezieht sich auf das Verhalten aller Felder eines bestimmten Datensatzes. Diese Option ist nicht verfügbar für Löschen, Suchen und Global Search.
Lesen:
Darf der User alle Felder des Datensatzes lesen.
Verhalten auf Listen:
- falls die Lesen ACL "false" zurückliefert, werden alle Felder in den jeweiligen Listenspalten mit einem Sensitive versehen, unabhängig davon ob die Felder Werte besitzen
- für die Bedingung der Lesen ACL stehen alle Felder des Datensatzes zur Verfügung, unabhängig von den gewählten selectFields der Query
Verhalten auf Layout:
- falls die Lesen ACL "false" zurückliefert, werden alle Felder auf dem jeweiligen Layout nicht angezeigt
Erstellen & Aktualisieren
Darf der User alle Felder des Datensatzes abändern
Verhalten:
- falls eine Erstellen- oder Aktualisieren ACL "false" zurückliefert, werden alle Felder auf "readonly" gesetzt. Der User darf sie zwar lesen aber nicht abändern
- falls dennoch verbotene Felder des Datensatzes geändert wurden, werden diese server-seitig wieder zurückgesetzt
3. Resource ist befüllt und Level ist ein Feld:
Eine ACL mit einem speziellen Feld als Level bezieht sich ausschließlich auf das angegebene Feld. Diese Option ist nicht verfügbar für Löschen, Suchen und Global Search.
Lesen:
Darf der User dieses Feld des Datensatzes lesen.
Verhalten auf Listen:
- falls die Lesen ACL "false" zurückliefert, wird dieses Feld in der jeweiligen Listenspalten mit einem Sensitive versehen, unabhängig davon, ob das Feld einen Wert besitzt
- für die Bedingung der Lesen ACL stehen alle Felder des Datensatzes zur Verfügung, unabhängig von den gewählten selectFields der Query
Verhalten auf Layout:
- falls die Lesen ACL "false" zurückliefert, wird dieses Feld auf dem jeweiligen Layout nicht angezeigt
Erstellen & Aktualisieren
Darf der User dieses Feld des Datensatzes abändern
Verhalten:
- falls eine Erstellen oder Aktualisieren ACL "false" zurückliefert, wird dieses Feld auf "readonly" gesetzt. Der User darf es zwar lesen aber nicht abändern
- falls das Feld dennoch auf dem Datensatz geändert wurde, wird es server-seitig wieder zurückgesetzt
Aus den vorangegangenen Regeln lassen sich folgende Workflows ableiten:
TODO: Restliche Typen erweitern
Benutzer definiert
Mit dem Benutzer definierten Typ lassen sich eigene Operationen definieren, die ein User im System machen kann.
Das ist z.b. die admin
Operation oder auch die supportInfo
Operation, um dem User zu verbieten die Supportinformationen einzusehen.
Teilen
Mit der 'Teilen' Operation lassen sich extra Regeln definieren, wann ein User etwas mit einem Datensatz machen kann. Diese gelten ZUSÄTZLICH zu den Entity Operationen. Dies ist Plattform seitig für alle teilbaren Datensätze (Shareable Entities) bereits vordefiniert.
Als Operationen gibt es hier: Lesen, Erstellen, Aktualisieren, Löschen, Suchen, Privat Teilen, Öffentlich Teilen, Für Usergruppen teilen
Die Resource ist hier auch eine Entity (siehe Abschnitt entity) und das Level ist ein bestimmter Datensatz.
Damit lässt sich nun definieren:
- Resource befüllt, Level ist
*
:- Dies beschreibt, ob ein User irgendwelche der Daten lesen/schreiben kann
- Bei den Teilen Operationen bestimmt dies, ob ein User einen Datensatz mit der entsprechenden Sichtbarkeit erstellen darf
- Welche Daten ein User sehen kann (Suchen)
- Resource befüllt, Level ist ein Datensatz
- Dies beschreibt, ob ein User genau diesen Datensatz lesen/schreiben kann
- Die 'Teilen' Operationen sind hier nicht verfügbar, da der Datensatz bereits erstellt wurde
Mandantschaft
Mit dieser ACL lassen sich die Mandanten Regeln definieren. Dies gilt zusätzlich zu Teilen und Entity und ist bereits plattform seitig für alle Entities eingestellt. Es gelten weiterhin der Root Tenant Modus und die Einstellungen aus dem Designer! Als Operationen gibt es hier Lesen, Erstellen, Aktualisieren, Löschen und Suchen.
Die Resource ist hier eine Entity und das Level entfällt.
Damit lässt sich nun definieren:
- Wann ein User einen Datensatz lesen/schreiben kann
- Welche Daten ein User sehen kann (Suchen)
Navigation
Mit dieser ACL lässt sich einstellen, welche Navigationseinträge ein Benutzer sehen kann. Es gibt hier keine Operationen.
Die Resource ist eine Application und das Level ist ein einzelner Eintrag oder *
Damit lässt sich nun definieren:
- Resource befüllt, Level
*
- Darf der Benutzer irgendeinen Eintrag aus dieser App sehen kann
- Resource befüllt, Level ist ein Eintrag
- Darf der Benutzer diesen einen Eintrag sehen
Layout
Mit dieser ACL lässt sich einstellen, welche Layouts ein Benutzer aufrufen kann. Operationen sind hier Lesen, Erstellen, Löschen. Aktuell ist nur Lesen verfügbar, die anderen Beiden kommen in einem späteren Feature
Die Resource ist eine Entity und das Level ein Layout der Entity.
Damit lässt sich definieren:
- Resource befüllt und Level
*
- Darf der User irgendwelche Layouts der Entity benutzen
- Resource befüllt und Level ist ein Layout
- Darf der User genau dieses Layout benutzen
ACL Orchestrierung
Um die Reihenfolge der ACLs zu bestimmen, gibt es mehrere Optionen um diese in Stufen zu organisieren. Bei der Auswertung einer Berechtigungsabfrage werden dann nur alle ACLs der untersten passenden Stufe ausgeführt, wobei dann eine davon ja ergeben muss um die ACL zu erfüllen.
Gewichtung
Die erste Option der Orchestrierung ist die ACL Gewichtung, ist eine ACL schwerer (größere Gewichtung), als eine gleichwertige andere ACL, gewinnt diese automatisch über die Andere, welche dann nicht mehr berücksichtigt wird bei der Abfrage.
Beispiel
Diese ACL hat ein Gewicht von 1000 und überschreibt damit die Operation "externalMessageRead" aus der anderen ACL, welche in diesem Beispiel noch wesentlich mehr Operationen enthält. Hier gibts es auch noch eine weitere ACL mit der gleichen Gewichtung, damit sind beide auf dem gleichen Level und werden beide ausgeführt.
Vorfahren
Die zweite Möglichkeit ACLs zu orchestrieren, besteht darin eine Hierarchie über die Vorfahren zu konstruieren. Dabei gibt es zwei verschiedene Varianten:
- Der Vorfahre einer Resource oder eines Levels das nicht das
*
ist, ist immer das*
. Siehe Beispiel 2. - Ist die Resource eine Entity, so ist der nächste Vorfahre sein
BasedOn
, gibt es kein Based on landet es bei*
Beispiel
Das Dashboard basiert auf einem Teilbaren Datensatz und überschreibt damit existierende ACL Einstellungen für die Read Operation.
Hier ist für das Navigationsitem "Chats" aus der PlatformApplication, die Einstellung für "alle" Einträge aus der PlatformApplication.