CodamAIDocs
Themafertig

Benutzerwechsel per Header

Wie eine berechtigte Person im Namen einer anderen Person arbeitet, mit den eigenen Rollen oder mit denen der Zielperson, und welche Prüfungen davor stehen.

Ausprägungen
mit Rolle, eigene Rollenmit Rolle, Rollen der Zielpersonohne Rolle → abgelehntZielperson unbekannt oder nicht im Mandanten → abgelehntNachschlagen nicht möglich → abgelehntungültiger Wert in user-roles → abgelehntohne Freigabe der Zielperson → abgelehntFreigabe für eigene Rollen, target verlangt → abgelehntFreigabe in einem anderen Mandanten → abgelehntFreigabe widerrufen → ab der nächsten Anfrage abgelehntDienstkonto eines freigestellten ClientsFreigabe abgeschaltet (consent=off)Freigabe beantragen, bestätigen, direkt erteilen, widerrufenwas wechselt und was bleibtAnlegenHistoriezusammen mit einem MandantenwechselBetriebsart SINGLE

Worum es geht

In Benutzer-Modellen sieht jede Person nur ihre eigenen Zeilen. Manchmal muss aber jemand genau das sehen, was eine bestimmte andere Person sieht, etwa der Support bei einer Fehlersuche. Dafür gibt es den Benutzerwechsel: Der Client schickt den Header user mit der ID der anderen Person, der Zielperson.

Die ID einer Person ist ihr Wert im Claim sub des Tokens, also ihre Keycloak-ID, eine lange Kennung wie 3f2a…. Der Login-Name funktioniert nicht.

Mit einem zweiten, freiwilligen Header wählst du, mit wessen Rechten du arbeitest:

Header user-rolesRollen, Gruppen und Attribute
fehlt oder owndeine eigenen
targetdie der Zielperson, so wie sie in ihrem eigenen Token stünden
jeder andere WertAnfrage wird abgelehnt

Groß- und Kleinschreibung spielt keine Rolle, Target gilt also wie target.

Was wechselt und was bleibt

Der RequestContext nach dem Wechsel
Wechselt immer
in beiden Modi
  • ID der Person (userId)
  • Name der Person (userName)
  • damit der Owner-Filter: du siehst die Zeilen der Zielperson
  • damit _userId beim Anlegen: neue Zeilen gehören der Zielperson
Bleibt immer
in beiden Modi
  • angemeldete Person: authenticatedUserId und authenticatedUserName bleiben deine
  • für CIAS selbst bist du der Handelnde: Verwaltung, Obergrenze, Audit
  • der Mandant der Anfrage
Hängt vom Modus ab
own = deine, target = die der Zielperson
  • Realm-Rollen
  • Fachrollen (Client-Rollen)
  • Gruppen
  • Attribute, also auch jeder Attributfilter

Mit target ist die Übernahme vollständig. Du bekommst auch Rollen, die du selbst nicht hast, sogar Plattformrollen der Zielperson. Es gelten dieselben Regeln wie bei einem echten Token der Zielperson:

  • Ist sie Mitglied der Organisation des Mandanten und trägt die Mitgliedschaft Rollen, ersetzen diese ihre globalen Fachrollen. Siehe Effektive Rollen.
  • Werte, die pro Mandant angemeldet sind, holt CIAS für die Zielperson, nicht für dich. Siehe Ein Wert pro Person oder pro Mandant.

Die Prüfungen der Reihe nach

Wird der Header user angewendet?
  1. CIAS
    Mandantenwechsel zuerst
    Trägt die Anfrage auch tenant, wird dieser Wechsel zuerst angewendet. Geprüft wird danach für den Mandanten, unter dem die Anfrage am Ende läuft.
  2. CIAS
    Rolle
    Hat die angemeldete Person die Realm-Rolle allowed-user-context-switch?
    ↳ nein 403 cias.authentication.user-switch-denied
  3. CIAS
    Zielperson nachschlagen
    Kann CIAS herausfinden, wer die Zielperson ist?
    ↳ nein 403 cias.authentication.user-switch-unavailable
  4. CIAS
    Zielperson bekannt?
    Gibt es eine Person mit dieser ID?
    ↳ nein 403 cias.authentication.user-switch-denied
  5. CIAS
    Mitglied im Mandanten?
    Nur wenn die Anfrage unter einem Mandanten läuft: Gehört die Zielperson dazu?
    ↳ nein 403 cias.authentication.user-switch-denied
  6. CIAS
    Freigabe der Zielperson
    Hat die Zielperson dir den Wechsel freigegeben, für diesen Mandanten und diesen Modus, und gilt die Freigabe noch? Wird bei jeder Anfrage neu gefragt.
    ↳ nein 403 cias.authentication.user-switch-not-consented, oder user-switch-unavailable, wenn die Frage nicht beantwortet werden kann
  7. ID und Name der Zielperson im RequestContext, Rollen je nach Modus

Ein Header user-roles mit einem anderen Wert als own oder target führt ebenfalls zu 403 cias.authentication.user-switch-denied.

Mitglied ist die Zielperson, wenn eines davon stimmt:

  • Sie ist Mitglied der Organisation mit dem Alias des Mandanten.
  • Ihr Attribut tenant nennt den Mandanten.
  • Ihr Attribut allowedTenants enthält den Mandanten.

Jede Ablehnung sieht gleich aus:

Ein abgelehnter Benutzerwechsel
Anfrage
POST /api/rest/note/query
Authorization: Bearer <Token von Lena>
user: 3f2a…
Antwort
HTTP 403
{ "error": "cias.authentication.user-switch-denied",
  "message": "request refused" }

Warum genau abgelehnt wurde, also Rolle, unbekannt oder nicht im Mandanten, steht nur im Log. So erfährt niemand über den Header, welche IDs es gibt.

Nur die fehlende Freigabe hat einen eigenen Schlüssel, cias.authentication.user-switch-not-consented. Sie wird erst geprüft, wenn feststeht, dass die Zielperson existiert und zum Mandanten gehört. Ein Client kann darauf reagieren und anbieten, eine Freigabe zu beantragen.

Was passiert mit dem Header user?
Realm-Rolle allowed-user-context-switchZielpersonHeader user-rolesNachschlagenFreigabe der ZielpersonErgebnis
––anderer Wert als own oder target––403 user-switch-denied
nein––––403 user-switch-denied
ja––nicht möglich–403 user-switch-unavailable
jaunbekannt–möglich–403 user-switch-denied
janicht Mitglied im Mandanten der Anfrage–möglich–403 user-switch-denied
jaMitglied, oder SINGLE–möglichkeine, abgelaufen, widerrufen, anderer Mandant oder nur own bei target403 user-switch-not-consented
jaMitglied, oder SINGLE–möglichnicht prüfbar403 user-switch-unavailable
jaMitglied, oder SINGLEfehlt oder ownmöglichown oder targetID und Name der Zielperson, deine Rollen und Attribute
jaMitglied, oder SINGLEtargetmöglichtargetID, Name, Rollen, Gruppen und Attribute der Zielperson

Woher CIAS die Zielperson kennt

Im Token steht nur die angemeldete Person. Über die Zielperson fragt CIAS deshalb nach und rechnet aus Keycloak nach, was in ihrem Token stünde:

  • ihre effektiven Realm-Rollen, auch solche aus zusammengesetzten Rollen und Standardrollen,
  • ihre effektiven Client-Rollen am Backend-Client,
  • ihre Organisationsmitgliedschaften mit den Rollen ihrer Organisationsgruppen,
  • ihre Benutzerattribute, für die der Client einen Attribut-Mapper hat, so wie CIAS sie anlegt.

Nicht nachgebildet werden Mapper auf anderen Client-Scopes und ein groups-Claim. Im Zweifel siehst du mit target also weniger als das echte Token der Zielperson, nie mehr.

Wie gefragt wird

Wann: CIAS mit seiner Benutzerverwaltung läuft im selben Programm wie CDMS, etwa im Hub.

Die Nachfrage ist ein einfacher Methodenaufruf.

Ergebnis: Nichts einzurichten.

Wann: CDMS und CIAS laufen als eigene Dienste.

CDMS fragt GET /cias/lookup/users/{sub}/identity?client=<backend-client>, mit demselben Dienst-Token wie für den Mandanten-Lookup. In CDMS steht dafür codamai.cias.tenancy.lookup=remote. In CIAS müssen codamai.cias.user.lookup-rest=true gesetzt sein (derselbe Schalter wie für den Attribut-Lookup) und die eigene Rollenliste codamai.cias.user.switch-lookup-roles (Umgebung CIAS_USER_SWITCH_LOOKUP_ROLES) die Rolle des Dienst-Tokens enthalten.

Ergebnis: Leere Rollenliste heißt: niemand darf fragen, jeder Wechsel endet mit user-switch-unavailable.

Die Rollenliste ist bewusst nicht die des Attribut-Lookups. Die Antwort enthält alle Rollen und Attribute einer Person, das ist mehr, als ein Attributwert verrät.

CDMS merkt sich eine Antwort je Person und Client 30 Sekunden lang (codamai.cias.attribute-lookup.ttl). Ist CIAS danach nicht erreichbar, greift CDMS nicht auf eine ältere Antwort zurück: Der Wechsel wird abgelehnt.

Die Freigabe der Zielperson

Eine Freigabe ist die Zustimmung einer Person, dass eine bestimmte andere Person in ihrem Namen arbeiten darf. Sie ist an alles gebunden, was den Wechsel ausmacht:

Teil der FreigabeBedeutung
Freigebende Persondie Zielperson, immer die angemeldete Person, die sie erteilt
Empfängergenau eine Person, nie eine Rolle oder Gruppe
Mandantder Mandant, in dem die Freigabe gilt. Ohne Mandanten (SINGLE) keiner
ModusOWN oder TARGET. TARGET schließt OWN ein
Endebis wann sie gilt. Ohne Ende nur, wenn die Installation es erlaubt
Grundfreiwillig, etwa eine Ticketnummer. Steht in der Mail und im Audit

Eine Freigabe für OWN deckt user-roles: target nicht ab. Eine Freigabe in acme deckt initech nicht ab.

Wie eine Freigabe entsteht

Zwei Wege zur Freigabe

Wann: Der Support braucht Zugriff, die Zielperson weiß noch nichts davon.

  1. 1
    Client→CIAS
    Lena schickt POST /cias/me/switch-requests mit target, mode, validUntil und reason. Dafür braucht sie die Rolle allowed-user-context-switch.
  2. 2
    CIAS
    legt den Antrag an und schickt Ben die Mail SWITCH_CONSENT_REQUESTED: wer fragt, mit wessen Rechten, bis wann, warum
  3. 3
    Client→CIAS
    Ben bestätigt mit POST /cias/me/switch-consents/{id}/approve, optional mit einem eigenen, kürzeren Ende. Oder er lehnt ab mit .../decline.

Ergebnis: Aus dem Antrag wird die Freigabe. Ein zweiter gleicher Antrag liefert den offenen zurück, ohne zweite Mail. Ein unbeantworteter Antrag verfällt nach CIAS_USER_SWITCH_REQUEST_EXPIRY (Standard 24 Stunden).

Wann: Ben will von sich aus, dass Lena diese Woche seine Vorgänge bearbeitet.

Ben schickt POST /cias/me/switch-consents mit grantee, mode, validUntil und reason. Freigebende Person ist immer Ben selbst, es gibt kein Feld, mit dem er jemand anderen eintragen könnte.

Ergebnis: Die Freigabe gilt sofort.

Was danach passiert:

  • Erste Nutzung: Beim ersten Wechsel, der auf der Freigabe beruht, bekommt Ben einmal die Mail SWITCH_CONSENT_USED.
  • Widerruf: DELETE /cias/me/switch-consents/{id}. Er wirkt mit der nächsten Anfrage, denn die Freigabe wird nie zwischengespeichert. Widerrufen dürfen Ben, Lena, ein Plattform-Admin und ein Mandanten-Admin (tenant-admin) im eigenen Mandanten. Erteilen darf nur Ben.
  • Überblick: GET /cias/me/switch-consents zeigt Ben, was er freigegeben hat, mit der ersten Nutzung. GET /cias/me/switch-consents/received zeigt Lena, was sie darf. Admins listen einen Mandanten unter GET /cias/admin/switch-consents.
  • Audit: Antrag, Freigabe, Ablehnung, Widerruf und erste Nutzung stehen als SwitchConsentEvent.* in der CIAS-Spur.

Für eine Freigabe, die du nicht sehen darfst, antwortet CIAS mit 404, als gäbe es sie nicht.

Was eine Installation einstellt

EinstellungUmgebungStandard
codamai.cias.user-switch.consentCIAS_USER_SWITCH_CONSENTrequired. off heißt: die Rolle allein entscheidet
codamai.cias.user-switch.consent-exempt-clientsCIAS_USER_SWITCH_CONSENT_EXEMPT_CLIENTSleer
codamai.cias.user-switch.max-consent-durationCIAS_USER_SWITCH_MAX_CONSENT_DURATIONkeine Grenze
codamai.cias.user-switch.allow-unlimited-consentCIAS_USER_SWITCH_ALLOW_UNLIMITED_CONSENTfalse, also braucht jede Freigabe ein Ende
codamai.cias.user-switch.request-expiryCIAS_USER_SWITCH_REQUEST_EXPIRYPT24H
codamai.cias.user-switch.revoker-rolesCIAS_USER_SWITCH_REVOKER_ROLEStenant-admin
codamai.cias.user-switch.consent-urlCIAS_USER_SWITCH_CONSENT_URLleer. Sonst steht die Adresse in den Mails

Jede Einstellung wirkt auch direkt als Umgebungsvariable, in jedem Programm, das CIAS einbindet. Ein unbekannter Wert bei consent verhindert den Start. Ein Ende in der Vergangenheit, über der Höchstdauer oder ein fehlendes Ende ohne Erlaubnis lehnt CIAS mit 422 cias.user.switch-consent-invalid ab.

Getrennt betrieben fragt CDMS die Freigabe bei GET /cias/lookup/users/{sub}/switch-consent?actor=…&tenantKey=…&mode=own|target ab, mit demselben Dienst-Token und denselben Rollen wie beim Nachschlagen der Zielperson. Anders als die Identität wird die Antwort nie gemerkt.

Varianten

Die Ausprägungen des Benutzerwechsels

Wann: Lena hat allowed-user-context-switch und schickt user: 3f2a…, ohne user-roles. Ben mit der ID 3f2a… ist Mitglied im Mandanten.

  1. 1
    Client→CDMS
    schickt POST /note/query mit Header user: 3f2a…
  2. 2
    CIAS
    liest das Token, bestimmt Mandant, Rollen und Attribute von Lena
  3. 3
    CIAS
    Rolle da, Ben bekannt und Mitglied → ID und Name := Ben, Rollen und Attribute bleiben Lenas
  4. 4
    CDMS→Database
    sucht mit _userId = 3f2a…

Ergebnis: Die Antwort enthält Bens Notizen, gefiltert mit Lenas Rechten.

Wann: Wie oben, dazu user-roles: target.

  1. 1
    Client→CDMS
    schickt POST /note/query mit user: 3f2a… und user-roles: target
  2. 2
    CIAS
    Rolle da, Ben bekannt und Mitglied
  3. 3
    CIAS
    ID, Name, Realm-Rollen, Fachrollen, Gruppen und Attribute := die von Ben
  4. 4
    CDMS→Database
    sucht mit _userId = 3f2a…, prüft Bens Rollen, filtert mit Bens Attributen

Ergebnis: Lena sieht, was Ben sieht, soweit Keycloak Bens Token nachbilden lässt.

Wann: Lena fehlt allowed-user-context-switch.

Der Header wird nicht übergangen, die ganze Anfrage wird abgelehnt.

Ergebnis: 403 cias.authentication.user-switch-denied.

Wann: Zur ID gibt es keine Person, oder sie gehört nicht zum Mandanten, unter dem die Anfrage läuft.

Beides endet gleich. Ein Tippfehler in der ID führt also nicht zu einer leeren Antwort, sondern zu einer Ablehnung.

Ergebnis: 403 cias.authentication.user-switch-denied.

Wann: CIAS ist nicht erreichbar, lehnt den Zugang ab, oder die Nachfrage ist nicht eingerichtet.

Ohne zu wissen, wer die Zielperson ist, wechselt CIAS nicht. Eine ältere Antwort wird nicht verwendet.

Ergebnis: 403 cias.authentication.user-switch-unavailable.

Wann: Die Anfrage schickt etwa user-roles: admin.

Ein unbekannter Wert wird nicht als own gelesen.

Ergebnis: 403 cias.authentication.user-switch-denied.

Wann: Lena hat die Rolle, Ben ist Mitglied, aber Ben hat Lena nichts freigegeben.

Rolle, Zielperson und Mitgliedschaft stimmen. Danach fragt CIAS nach der Freigabe und findet keine. Es wird nichts gewechselt.

Ergebnis: 403 cias.authentication.user-switch-not-consented. Lena kann einen Antrag stellen.

Wann: Ben hat Lena OWN freigegeben, Lena schickt user-roles: target.

OWN deckt target nicht ab. Dieselbe Anfrage ohne user-roles geht durch.

Ergebnis: 403 cias.authentication.user-switch-not-consented.

Wann: Bens Freigabe gilt für acme, Lena arbeitet unter initech.

Eine Freigabe gilt genau in einem Mandanten.

Ergebnis: 403 cias.authentication.user-switch-not-consented.

Wann: Ben widerruft, während Lena arbeitet, oder das Ende ist erreicht.

Die Freigabe wird bei jeder Anfrage neu geprüft. Die nächste Anfrage endet bereits mit der Ablehnung.

Ergebnis: 403 cias.authentication.user-switch-not-consented.

Wann: Ein technischer Client, etwa ein Import, steht in CIAS_USER_SWITCH_CONSENT_EXEMPT_CLIENTS und wechselt mit seinem eigenen Dienstkonto-Token.

Ein Dienstkonto kann niemanden um Freigabe bitten. CIAS erkennt das Token daran, dass azp der Client ist und preferred_username service-account-<client> lautet. Eine Person, die sich über denselben Client anmeldet, ist nicht freigestellt.

Ergebnis: Der Wechsel braucht keine Freigabe. Rolle, Zielperson und Mitgliedschaft werden weiter geprüft.

Wann: CIAS_USER_SWITCH_CONSENT=off

Die Installation entscheidet bewusst, dass die Rolle allein reicht. Beim Start steht dazu eine Warnung im Log.

Ergebnis: Der Wechsel funktioniert ohne Freigabe, die anderen Prüfungen bleiben.

Wann: Mit wirksamem Wechsel wird ein Objekt eines Benutzer-Modells angelegt, in beiden Modi.

CDMS setzt _userId auf die ID der Zielperson. Das neue Objekt gehört ihr, und ohne Wechsel siehst du es nicht mehr.

Ergebnis: So lassen sich Daten für eine andere Person anlegen. Ein mitgeschicktes _userId im JSON bewirkt das nicht.

Wann: Mit wirksamem Wechsel wird ein auditiertes Modell geändert.

Die Revision nennt als Benutzer-ID und Namen die Zielperson. Zusätzlich hält sie ID und Namen der angemeldeten Person als handelnde Person fest. In der Historie steht deren Name in actingUsername.

Ergebnis: Siehe Was eine Revision festhält.

Wann: Die Anfrage trägt die Header tenant und user.

Jeder Wechsel braucht seine eigene Realm-Rolle. Zuerst wird der Mandant gewechselt, nach den Regeln unter Mandantenwechsel per Header. Danach wird die Person gewechselt, und die Mitgliedschaft der Zielperson wird für den Ziel-Mandanten geprüft.

Ergebnis: Du arbeitest als die Zielperson im anderen Mandanten, mit deinen Rollen oder mit ihren.

Wann: CODAMAI_PERSISTENCE_TENANT_MODE=SINGLE

Es gibt keinen Mandanten, also entfällt die Prüfung der Mitgliedschaft. Rolle, Nachschlagen und bekannte Zielperson werden weiter geprüft.

Ergebnis: Den Owner-Filter gibt es in beiden Betriebsarten, also auch den Wechsel.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CIAS/cias-authentication – JwtSessionFilter (Header user und user-roles), TokenParser.switchUser (Reihenfolge: Mandantenwechsel, dann Benutzerwechsel), SwitchTargetLookup, RequestAdmission (USER_SWITCH_DENIED, USER_SWITCH_UNAVAILABLE)
  • CIAS/cias-kernel – SwitchTargetPort
  • CIAS/cias-user – LocalSwitchTargetAdapter, SwitchTargetLookupController (GET /cias/lookup/users/{sub}/identity), SwitchTargetLookupRoles (codamai.cias.user.switch-lookup-roles)
  • CIAS/cias-iam-api – RepresentedIdentityPort
  • CIAS/cias-iam-keycloak – KeycloakRepresentedIdentityAdapter (effektive Realm- und Client-Rollen, Organisationen mit Rollen, Attribute mit Mapper)
  • CIAS/cias-tenancy-client – RemoteSwitchTargetAdapter (codamai.cias.tenancy.lookup=remote, Merkzeit codamai.cias.attribute-lookup.ttl)
  • CDMS/cdms-system-layer – AbstractLayer (set_userId beim Create, Owner-Filter über getUserId)
  • CDMS/cdms-persistence-database – AuditRevisionEntity (acting_user_id, acting_username), AuditRevisionListener (userId, username, handelnde Person aus dem RequestContext)
  • CDMS/cdms-commons – AuditRevisionMeta (actingUsername)
  • CIAS/cias-authentication – UserSwitchPolicy (codamai.cias.user-switch.consent, consent-exempt-clients), RequestAdmission.USER_SWITCH_NOT_CONSENTED
  • CIAS/cias-kernel – SwitchConsentQuery, SwitchConsentCheck
  • CIAS/cias-user – SwitchConsent, SwitchConsentService, SwitchConsentController (/cias/me/switch-consents, /cias/me/switch-requests, /cias/admin/switch-consents), GET /cias/lookup/users/{sub}/switch-consent, SwitchConsentPolicy
  • CIAS/cias-notification – Vorlagen SWITCH_CONSENT_REQUESTED, SWITCH_CONSENT_USED
Suchen