CodamAIDocs
Themafertig

Ein Wert pro Person oder pro Mandant

Ein Attribut gilt entweder für die Person in allen Mandanten (USER) oder je Mandant getrennt (USER_IN_TENANT). Wie der passende Wert ins Token und in den Attributfilter kommt, wenn eine Person mehreren Mandanten angehört.

Ausprägungen
USER: ein Wert für alle MandantenUSER_IN_TENANT: ein Wert je MandantPerson mit einem MandantenPerson mit mehreren MandantenCIAS nicht erreichbar

Worum es geht

Anna arbeitet für zwei Mandanten: nordbau und suedlogistik. In nordbau ist sie für die Region Nord zuständig, in suedlogistik für Süd. Ein einziger Wert region am Konto kann das nicht ausdrücken. Welchen Wert soll er haben?

Deshalb sagt jedes Attribut bei der Anmeldung, worüber es etwas aussagt:

BindungbedeutetBeispieleWo der Wert liegt
USERein Wert pro Person, in jedem Mandanten derselbeSprache, Personalnummer, Anzeigenameam Konto in Keycloak, kommt über das Token
USER_IN_TENANTein Wert je Person und MandantRegionen, Werke, Kostenstellenin CIAS, je Person und Mandant

Wie ein Attribut pro Mandant wird

Das Modul sagt es bei der Anmeldung, siehe Attribute anmelden:

Attribute.optional("region").asMultivalued().perTenant()

Nur das anmeldende Modul weiß, was es meint: CIAS sieht, dass ein Attribut region heißt, aber nicht, ob eine Installation einer Person in zwei Mandanten verschiedene Regionen gibt. Was CDMS aus dem Modell erzeugt, ist immer USER, siehe Zwei Herkünfte von Attributen. Ein Attribut pro Mandant schreibt ein Modul in seiner Anmeldung selbst.

Die Werte schreibst du über POST /cias/admin/users/{id}/tenant-attributes?tenantKey=…, geprüft durch Delegation und Obergrenze, siehe Wer ein Attribut schreiben darf. Das geht nur für Attribute, die im Katalog pro Mandant stehen. Ein USER-Attribut wie locale lehnt CIAS dort ab, auch für einen Plattform-Administrator.

Das Szenario

Anna in zwei Mandanten
  1. 1
    Admin→CIAS
    schreibt für Anna in nordbau: region = [nord]
  2. 2
    Admin→CIAS
    schreibt für Anna in suedlogistik: region = [sued]
  3. 3
    Client→CDMS
    Anna fragt Aufträge ab, Mandant nordbau
  4. 4
    CIAS
    prüft das Token, legt den Mandanten fest, holt Annas Werte für nordbau
  5. 5
    CDMS
    filtert mit region IN (nord)
  6. 6
    Client→CDMS
    Anna wählt suedlogistik und fragt erneut
  7. 7
    CDMS
    filtert mit region IN (sued)
    Ergebnis: Dieselbe Person, dasselbe Token, je Mandant andere Zeilen

Vorher und nachher

flowchart LR
    subgraph T["Im Token von Anna"]
      TR["region: nord, sued<br/>(ein Wert fürs ganze Konto)"]
      TL["locale: de"]
    end
    subgraph C["In CIAS, Mandant suedlogistik"]
      CR["region: sued"]
    end
    subgraph E["Effektiv in suedlogistik"]
      ER["region: sued"]
      EL["locale: de"]
    end
    CR -- "ersetzt" --> ER
    TL -- "unverändert" --> EL
    TR -. "wird ersetzt" .-> ER

Der Wert aus CIAS ersetzt den Wert aus dem Token für diesen Schlüssel. Alle anderen Attribute, etwa locale, kommen unverändert aus dem Token. Das gilt auch dann, wenn CIAS für so einen Schlüssel doch eine Zeile im Mandanten führt: Ersetzt wird nur, was die Anwendung selbst mit perTenant() anmeldet. Würde CIAS mischen, wäre der Filter in einem Mandanten breiter als in jedem einzelnen, genau das soll verhindert werden.

Die Ausprägungen

Welcher Wert gilt

Wann: Das Attribut ist ohne Bindung oder mit USER angemeldet.

CIAS nimmt den Wert aus dem Token, in jedem Mandanten denselben. Es gibt keine zusätzliche Abfrage.

Ergebnis: Wert aus dem Token

Wann: Das Attribut ist mit perTenant() angemeldet.

CIAS holt bei jeder Anfrage mit Mandant die Werte der Person in diesem Mandanten und setzt sie ein.

Ergebnis: Wert aus CIAS für den aktiven Mandanten

Wann: Die Person gehört genau einem Mandanten an.

Es gilt dasselbe wie bei mehreren: Der Wert kommt aus CIAS für diesen einen Mandanten. Der Unterschied zu USER zeigt sich erst, wenn ein zweiter Mandant dazukommt.

Ergebnis: Wert aus CIAS

Wann: Die Person ist Mitglied mehrerer Mandanten und wählt einen davon für die Anfrage.

Der Wert kommt für den gewählten Mandanten. Beim privilegierten Wechsel in einen Mandanten, in dem die Person nicht Mitglied ist, bestimmt CIAS die Werte vorher, für den Ausgangsmandanten, und sie gelten im Ziel weiter, wie die Rollen. Siehe Zwischen Mandanten wechseln.

Ergebnis: je Mandant ein eigener Wert

Wann: Die Abfrage der Werte scheitert.

Hat CIAS die Werte dieser Person in diesem Mandanten zwischengespeichert, gelten diese, auch wenn sie älter sind. Sonst lehnt CIAS die Anfrage ab. Ein Ausfall soll niemandem mehr Reichweite geben und niemandem nehmen, womit er schon gearbeitet hat.

Ergebnis: Pufferwert, oder 403 cias.authentication.tenant-not-served

Woher die Werte kommen

Wer beantwortet die Abfrage?
BetriebsartWas muss vorhanden seinAbfrage
eingebettetcias-user mit codamai.cias.user.persistence=jpaMethodenaufruf im selben Programm
getrenntcias-tenancy-client im Modul; im CIAS codamai.cias.user.lookup-rest=true und codamai.cias.user.lookup-roles mit der Rolle des abfragenden DienstesGET /cias/lookup/users/{sub}/attributes über HTTP
egalein Modul meldet ein Attribut pro Mandant an, aber nichts kann die Werte abfragendie Anwendung startet nicht, die Meldung nennt die Attribute
getrenntEndpunkt im CIAS nicht eingeschaltet oder Rolle fehltjede Anfrage mit Mandant wird abgelehnt: 403 cias.authentication.tenant-not-served

Die Antwort merkt sich CIAS je Person und Mandant für 30 Sekunden, einstellbar mit codamai.cias.attribute-lookup.ttl. Die Zahl der gemerkten Paare begrenzt codamai.cias.attribute-lookup.max-entries. Die Abfrage kostet also höchstens einen Aufruf je Person, Mandant und halbe Minute. Eine Installation ohne Attribut pro Mandant fragt nie.

Eine Anfrage ohne Mandant, etwa in der Betriebsart SINGLE, hat keine Werte pro Mandant. Dort gilt der Wert aus dem Token.

Fallen

Weiter

Quellen im Code und in der Wissensdatenbank
  • commons – models.AttributeBinding (USER, USER_IN_TENANT), models.Attribute.perTenant()
  • CIAS/cias-authentication – TokenParser (admit, boundAttributesFor), EffectiveAttributes.resolve, AttributeLookup (exactlyTheDeclaredAttributes), DeclaredTenantBoundAttributes, AttributeLookupProperties (codamai.cias.attribute-lookup.ttl, max-entries), TenantBoundAttributeWiringCheck, RequestAdmission.TENANT_NOT_SERVED
  • CIAS/cias-authorization – AttributeWritePermission (Bindung), RemoteModuleDeclarationAdapter (binding über GET /cias/fetch)
  • CIAS/cias-user – TenantBoundAttributeService, TenantBoundAttributeReader (cias_user_attribute.tenant_key), LocalTenantBoundAttributeAdapter, AttributeLookupController (GET /cias/lookup/users/{externalUserId}/attributes), CiasUserConfiguration (lookup-rest, lookup-roles)
  • CIAS/cias-tenancy-client – RemoteTenantBoundAttributeAdapter
  • CDMS/cdms-scaffold – CdmsReadmeWriter (Tenant-bound attributes)
  • CIAS/cias-authentication/docs/adr – ADR-042; CIAS/cias-kernel/docs/adr – ADR-022
Suchen