Zum Inhalt springen

Rollen und Rechte

Kurzantwort: Rechte greifen auf drei Ebenen: Modell (welche Rolle für welche Operation), Feld (Feldrollen) und Zeile (Owner-Filter und Attributfilter). Die Modellrollen kommen aus @AccessByRole und werden gegen die Client-Rollen des Tokens geprüft. Ist keine Rolle gesetzt, ist die Operation frei.


flowchart TB
    R["Request"] --> M{"Modellrolle vorhanden<br/>und im Token?"}
    M -->|nein und Strict| E403["403 missing-permission"]
    M -->|nein und tolerant| SKIP["Operation liefert nichts / false"]
    M -->|ja| F["Feldrollen: welche Felder<br/>lesbar/schreibbar sind"]
    F --> Z["Zeilenfilter:<br/>_userId (Owner)<br/>+ Attributfilter"]
    Z --> DB[(Daten)]
@AccessByRole(onCreate = "crm/customer-create",
onRead = "crm/customer",
onUpdate = "crm/customer-update",
onDelete = "crm/customer-delete",
onDownload = "", onHistory = "", onRollback = "")

Geprüft wird in AbstractAuthorizationLayer gegen RequestContext.getEffectiveUserRoles() – das sind die Client-Rollen aus resource_access.<cias_client>.roles.

PrüfmethodeOperationFehler bei fehlender Rolle
createAccessAllowedByClassCreatemissing-create-role bzw. missing-permission|<rolle>
readAccessAllowedByClassRead/Querymissing-permission|<rolle>
updateAccessAllowedByClassUpdate/Patchmissing-update-role
deleteAccessAllowedByClassDeletemissing-permission|<rolle>
downloadAccessAllowedByClassDateidownloadmissing-permission|<rolle>
historyAccessAllowedByClassHistorie lesenmissing-permission|<rolle>
rollbackAccessAllowedByClassRollbackmissing-rollback-role

Ist keine Rolle konfiguriert (null), ist die Operation erlaubt. Rechte sind also opt-in pro Modell.

Das Verhalten bei fehlender Rolle hängt am Strict Mode: strikt → MissingPermissionException (403), tolerant → die Prüfung liefert false und der Aufrufer liefert nichts zurück.

Format (Vorschau im Frontend, verbindlich ist das Backend):

%ordnerpfad%/%modellname%{-aktion}
SituationRollenname
Modell Question in audits/checklisten, keine Einschränkungaudits/checklisten/question
dasselbe, READ eingeschränktaudits/checklisten/question-read
Modell Tenant ohne Ordnertenant
dasselbe, DELETE eingeschränkttenant-delete
  • Die Standardrolle (ohne Aktionssuffix) erlaubt alle Aktionen.
  • Wird eine Aktion aktiv eingeschränkt, ist zusätzlich die Aktionsrolle erforderlich.
  • Bestandteile werden normalisiert: Kleinschreibung, Leerzeichen zu -.

Alle Rollen eines Systems sammelt der Generator in RoleRegistryService.

ArtQuelle im Tokenwofür
Realm-Rollenrealm_access.rolesadministrative Rechte der Plattform: allowed-tenant-context-switch, allowed-user-context-switch, Mandantenverwaltung
Client-Rollenresource_access.<cias_client>.rolesfachliche Rechte auf Modellen und Feldern

Die Modellprüfung benutzt Client-Rollen, der Kontextwechsel Realm-Rollen.

@AccessFieldByRole(onCreate = "", onRead = "…", onUpdate = "…", onDelete = "")

Die Feldrollen stehen in MetaFieldInfo (createRole, readRole, updateRole, deleteRole) und werden vom generierten {Model}AttributeFilter bzw. beim Aufbau der Antwort ausgewertet. Ein Feld ohne Leserecht erscheint nicht in der Antwort; im Strict Mode führt die ausdrückliche Anforderung eines solchen Feldes zum Fehler.

Erbt ein Modell von AbstractUserModel, ergänzt der System-Layer bei jeder Abfrage:

_userId EQ <RequestContext.userId>

Dieser Filter ist als mandatory markiert: Lässt er sich nicht in ein Datenbank-Prädikat übersetzen, scheitert die Anfrage – er wird nie stillschweigend weggelassen.

Siehe Attributbasierte Filter.

Update, Patch, Delete und Rollback laden ihr Ziel über einen ungefilterten find. Damit die bloße Kenntnis einer ID nicht genügt, prüft der System-Layer vorher assertVisibleForWrite(id): dieselben Filter wie beim Lesen. Eine nicht sichtbare Zeile wird als 404 gemeldet, nicht als 403 – „existiert, gehört dir aber nicht” würde die Existenz fremder Daten verraten.

Der Mandant ist kein Filter, sondern die Wahl der Datenbank – siehe Mandantentrennung.

Rechteprüfung findet im System-Layer und in cdms-authorization statt, nicht in der Persistenz. Wer die Persistenz direkt aufruft, umgeht Owner- und Attributfilter. Das ist beabsichtigt (Infrastruktur ohne Fachautorisierung), muss bei neuen Aufrufern aber bewusst berücksichtigt werden.