Worum es geht
Manche Daten gehören einer einzelnen Person: Notizen, Entwürfe, persönliche Einstellungen. Dafür gibt es Benutzer-Modelle (Ebene USER). Jede Zeile eines Benutzer-Modells hat ein Systemfeld _userId, die ID der Person, der sie gehört.
CDMS hängt an jede Anfrage auf ein Benutzer-Modell eine Bedingung an: _userId = angemeldete Person. Diese Bedingung heißt Owner-Filter. Du siehst sie nicht in deiner Anfrage und kannst sie nicht abschalten.
Wann du ein Modell auf die Ebene USER setzt, steht unter Modell-Ebenen.
Zwei Personen, eine Tabelle
flowchart LR
subgraph T["Tabelle note in der Datenbank des Mandanten"]
R1["Einkaufsliste<br/>_userId = anna"]
R2["Urlaubsplan<br/>_userId = anna"]
R3["Projektideen<br/>_userId = ben"]
end
A(["Anna: POST /note/query"]) --> F1{"_userId = anna"}
B(["Ben: POST /note/query"]) --> F2{"_userId = ben"}
F1 --> R1
F1 --> R2
F2 --> R3
Beide schicken dieselbe Suche. Anna bekommt zwei Treffer, Ben einen. totalCount zählt jeweils nur die eigenen Zeilen.
Woher die ID kommt
Die ID der Person steht im Token, standardmäßig im Claim sub. CIAS liest sie bei jeder Anfrage aus und gibt sie an CDMS weiter. Der Client schickt sie nie selbst mit.
Varianten
Wann: POST /note/create
-
1Client→CDMSschickt die Notiz, mit oder ohne
_userId -
2CDMSsetzt
_userIdauf die ID der angemeldeten Person, ein mitgeschickter Wert zählt nicht -
3CDMS→Databasespeichert die Notiz
Ergebnis: Die Notiz gehört immer der Person, die sie anlegt.
Wann: POST /note/read/{id}
-
1CDMS→Databaseliest die Zeile mit
idund_userId = angemeldete Person -
2CDMSkeine Zeile gefunden → 404
not-found
Ergebnis: Eine fremde Notiz sieht aus wie eine, die es nicht gibt.
Wann: POST /note/query
CDMS verbindet deine Filter mit UND mit _userId = angemeldete Person. Fremde Zeilen fehlen in data und zählen nicht in totalCount.
Ergebnis: Auch Listen in einer response, z. B. die Notizen an einem anderen Objekt, zeigen nur die eigenen Zeilen.
Wann: PUT, PATCH, DELETE, rollback
-
1CDMS→Databasezählt die Zeile mit
idund_userId = angemeldete Person -
2CDMS0 → 404
not-found|<Dto>|<id>, noch vor der Rollenprüfung -
3CDMS1 → weiter wie gewohnt;
_userIdbleibt unverändert, auch wenn der Client einen anderen Wert schickt
Ergebnis: Niemand kann eine Zeile einer anderen Person übernehmen oder sich selbst eine Zeile zuschieben.
Wann: Ein Create legt über eine Beziehung Objekte eines Benutzer-Modells mit an.
Jedes mitangelegte Objekt eines Benutzer-Modells bekommt ebenfalls die ID der angemeldeten Person als _userId.
Ergebnis: Alles, was eine Anfrage anlegt, gehört derselben Person.
Entscheidungstabelle
| _userId der Notiz | Rolle für die Operation | Ergebnis |
|---|---|---|
| anna | ja | erlaubt |
| anna | nein | 403 missing-permission|<rolle> |
| ben | – | lesen, ändern, löschen: 404; suchen: fehlt in der Liste |
Technische Clients
Ein Server, der sich mit Client Credentials anmeldet, hat keine echte Person. Im Token steht dann die ID seines Dienstkontos. Für den Owner-Filter ist das Dienstkonto eine Person wie jede andere:
- Was der Server anlegt, gehört dem Dienstkonto.
- Der Server sieht nur Zeilen, die das Dienstkonto selbst angelegt hat, keine Zeilen echter Personen.
Soll ein Dienst Daten echter Personen bearbeiten, ist ein Benutzer-Modell meist die falsche Wahl. Nimm dann ein Mandanten-Modell und schränke es mit einem Attributfilter oder einem eigenen Filter ein.
Im Auftrag einer anderen Person
In CDMS gibt es keine Rolle, die den Owner-Filter aufhebt, auch für Administratoren nicht. Muss jemand die Daten einer bestimmten Person sehen, nutzt er den Benutzerwechsel von CIAS: Wer die Realm-Rolle allowed-user-context-switch hat, schickt im Header user die ID der anderen Person. Die Person muss es geben, sie muss, wenn die Anfrage unter einem Mandanten läuft, zu diesem Mandanten gehören, und sie muss den Wechsel freigegeben haben. Sonst antwortet CIAS mit 403. Der Owner-Filter arbeitet danach mit ihrer ID und zeigt genau ihre Zeilen. Ob dabei deine Rollen gelten oder ihre, wählst du mit dem Header user-roles. Mehr unter Benutzerwechsel per Header.
Fallen
Wie es weitergeht
- Sichtbarkeit nach einem Profilattribut statt nach Person: Attributfilter
- Warum fremde Zeilen 404 liefern: Warum Unsichtbares 404 liefert
- Alle Filter einer Suche im Überblick: Filter, die immer mitlaufen