CodamAIDocs
Themafertig

Attribute anmelden

Wie ein Modul ein Attribut deklariert, warum ein Pflichtattribut einen Standardwert braucht und wie der Attributkatalog entsteht.

Ausprägungen
optionalPflicht mit StandardwertPflicht ohne Standardwert → abgewiesenVorliebe der Personpro Mandant

Worum es geht

Ein Modul meldet seine Attribute in derselben Deklaration an wie seine Rollen, siehe Module melden ihre Rollen an. Eine Deklaration ist die Liste, mit der ein Modul sagt: „Das brauche ich.“ CIAS liest sie beim Abgleich und macht daraus drei Dinge:

  1. einen Eintrag im Benutzerprofil von Keycloak, damit ein Konto den Wert überhaupt speichern kann,
  2. einen Claim-Mapper am Client des Moduls, damit der Wert im Token ankommt,
  3. einen Eintrag im Attributkatalog von CIAS, der festhält, wer das Attribut angemeldet hat und wer es schreiben darf.

Was eine Anmeldung enthält

Jedes Attribut hat sechs Teile:

TeilBedeutungfehlt es …
keyder Name, genau so im Profil und im TokenPflicht
multivaluedeine Liste statt eines Werts. Ein Attributfilter braucht fast immer eine Listeein Wert
defaultValuewas Konten bekommen, die älter sind als das Attributkein Standardwert
requireddas Modul kann ohne den Wert nicht arbeitenoptional
selfEditabledie Person darf den Wert selbst ändernnur Administratoren
bindingUSER: ein Wert pro Person. USER_IN_TENANT: ein Wert je Person und MandantUSER

In Java schreibt ein Modul das mit kurzen Bausteinen:

Attribute.optional("region").asMultivalued()          // optional, Liste
Attribute.required("customerId", "unbekannt")         // Pflicht, mit Standardwert
Attribute.preference("locale", "de")                  // die Person ändert es selbst
Attribute.optional("areas").asMultivalued().perTenant() // eine Liste je Mandant

Ein getrennt laufendes Modul liefert dieselbe Liste als JSON unter GET /cias/fetch:

Anfrage
GET /cias/fetch
Antwort
{
  "roles": [ … ],
  "attributes": [
    { "key": "region", "multivalued": true, "defaultValue": null,
      "required": false, "selfEditable": false, "binding": "USER" }
  ]
}

Das Feld binding kommt dabei genauso an wie im eingebetteten Betrieb. Fehlt es, gilt USER, so wie bei einem Modul, das älter ist als das Feld. Einen Wert, den CIAS nicht kennt, rät es nicht: Die Anmeldung dieses Moduls gilt dann wie ein nicht erreichbares Modul, und beim Abgleich bleibt alles, wie es war.

Formatregeln wie eine Länge oder ein Muster kann eine Anmeldung nicht enthalten. Ob eine neue Regel sicher ist, hängt von den Werten ab, die schon in den Konten stehen, und die kennt das Modul nicht. Solche Regeln pflegt, wer den Realm betreibt, von Hand im Benutzerprofil. CIAS lässt sie dort stehen.

Die Ausprägungen

Wie ein Attribut angemeldet sein kann

Wann: required ist false. So meldet CDMS jedes Attribut aus dem Modell an.

Das Konto darf ohne Wert sein. Was das Modul dann tut, entscheidet das Modul. Ein Attributfilter in CDMS lehnt die Anfrage ab, wenn der Wert fehlt.

Ergebnis: angenommen

Wann: required ist true, defaultValue ist gesetzt.

Keycloak füllt den Standardwert bei allen Konten ein, die ihn noch nicht haben. Pflicht ist der Wert für eine Person, die ein Formular ausfüllt, nie für CIAS, das über die Verwaltungs-API schreibt.

Ergebnis: angenommen

Wann: required ist true, defaultValue fehlt oder ist leer.

Alle Konten, die älter sind als das Attribut, hätten keinen Wert. Keycloak lehnt dann jede Änderung an so einem Konto ab, auch das Sperren. Das Recht zu entziehen wäre das Erste, was kaputtgeht.

Ergebnis: abgewiesen: die ganze Deklaration dieses Moduls, auch seine Rollen, Status REJECTED

Wann: selfEditable ist true, etwa bei locale.

Die Person darf den Wert selbst ändern, auch auf Keycloaks eigener Kontoseite. Administratoren dürfen es weiterhin.

Ergebnis: angenommen

Wann: binding ist USER_IN_TENANT.

Die Person kann in jedem Mandanten einen anderen Wert haben. Die Werte führt CIAS, nicht Keycloak. Siehe Ein Wert pro Person oder pro Mandant.

Ergebnis: angenommen

Wann CIAS eine Anmeldung abweist

Was stimmt nicht mit den Attributen?
BefundbetrifftFolge
Pflichtattribut ohne Standardwertein ModulREJECTED: die ganze Deklaration des Moduls fällt aus diesem Lauf
dasselbe Attribut zweimal verschieden im selben Modulein ModulREJECTED
der Katalog führt das Attribut für ein anderes Modul, und dieses Modul beschreibt es andersein ModulREJECTED
zwei Module beschreiben dasselbe Attribut im selben Lauf verschiedenallesSKIPPED: der Lauf schreibt nichts, für kein Modul
zwei Module beschreiben dasselbe Attribut gleich–kein Widerspruch, beide dürfen es anmelden

Warum so streng? Das Benutzerprofil ist ein Dokument für den ganzen Realm. Zwei verschiedene Beschreibungen desselben Attributs beschreiben dasselbe Feld, und wer zuletzt schriebe, gewönne. Das merkte niemand, bis ein Filter falsche Zeilen liefert.

Was in Keycloak entsteht

Ein Abgleich mit einem neuen Attribut region
  1. 1
    CIAS→Keycloak
    trägt region ins Benutzerprofil ein: mehrwertig, sehen dürfen Administrator und Person, ändern nur Administratoren, kein Standardwert, nicht Pflicht
  2. 2
    CIAS→Keycloak
    legt am Client des Moduls einen Claim-Mapper region an: Wert des Attributs → Claim region in Access-Token, ID-Token und UserInfo, als Liste
  3. 3
    CIAS
    legt im Katalog den Eintrag region an, Eigentümer cdms
    Ergebnis: Ab jetzt kann ein Konto region tragen, und das Token des Clients bringt es mit

Das Profil schreibt CIAS einmal pro Lauf für alle Module zusammen, denn Keycloak ersetzt es bei jedem Schreiben ganz. Was CIAS nicht angemeldet hat, bleibt darin stehen, auch Regeln und Anzeigenamen, die jemand von Hand gepflegt hat. Ändert ein Modul seine Anmeldung, etwa von einem Wert auf eine Liste, passt der nächste Abgleich Profil und Mapper an.

Der Attributkatalog

Den Katalog liest jede angemeldete Person:

Anfrage
GET /cias/admin/attributes/region
Antwort
HTTP 200
{
  "key": "region",
  "module": "cdms",
  "displayName": "region",
  "description": null,
  "group": null,
  "multivalued": true,
  "required": false,
  "defaultValue": null,
  "selfEditable": false,
  "binding": "USER",
  "assignableBy": [],
  "deprecatedAt": null
}
FeldBedeutung
modulewer das Attribut angemeldet hat. Solange es angemeldet ist, kann kein anderes Modul es anders beschreiben
displayName, description, groupfür Verwaltungsseiten. Die Anmeldung nennt sie nicht; der Name ist daher der Schlüssel
assignableBywelche Rollen den Wert je Mandant schreiben dürfen. Leer heißt: nur Plattform-Administratoren. Siehe Wer ein Attribut schreiben darf
deprecatedAtgesetzt, wenn kein Modul das Attribut mehr anmeldet. Siehe Wie ein Attribut wieder verschwindet

Der Katalog ist nur lesbar. Einträge entstehen allein durch den Abgleich: Ein Attribut gibt es, weil ein Modul es braucht. GET /cias/admin/attributes liefert alle Einträge, ohne Anmeldung gibt es 403, für einen unbekannten Schlüssel 404.

Fallen

Weiter

Quellen im Code und in der Wissensdatenbank
  • commons – models.Attribute (key, multivalued, defaultValue, required, selfEditable, binding; optional, required, preference, asMultivalued, perTenant), models.AttributeBinding
  • CIAS/cias-authorization – RoleReconciliationService (defect, attributeContradictions, attributeTakenFromAnotherModule, writeProfile, deliver, catalogueAttributes), DeclaredAttribute (declare, redeclare, delegateTo)
  • CIAS/cias-authorization – AttributeCatalogService, AttributeAdminController (GET /cias/admin/attributes, /cias/admin/attributes/{key}), AttributeView
  • CIAS/cias-iam-api – ProfileAttribute (requiredForUser); CIAS/cias-iam-keycloak – KeycloakAttributeAdapter (ensureAttributes, apply, ensureClaim)
  • CIAS/cias-authorization/docs/adr – ADR-025, ADR-026, ADR-032, ADR-040; CIAS/cias-authentication/docs/adr – ADR-042
Suchen