Worum es geht
Der Keycloak-Adapter (cias-iam-keycloak) ist das einzige Stück von CIAS, das Keycloak kennt. Er setzt die Ports um, indem er die Admin-REST-API von Keycloak aufruft. Das ist die HTTP-Schnittstelle, über die man einen Realm auch von außen verwalten kann: Konten anlegen, Rollen vergeben, Gruppen pflegen.
Dafür meldet sich CIAS bei Keycloak selbst an, mit einem eigenen Dienstkonto. Das ist ein Client ohne Anmeldemaske, der nur Verwaltungsrechte hat. Im mitgelieferten Realm heißt er cias-admin.
Was der Adapter in Keycloak anfasst
flowchart TB
subgraph R["Realm (z. B. codamai)"]
U["Konten<br/>Benutzername = E-Mail"]
O["Organisationen<br/>Alias = Mandantenschlüssel"]
OG["Gruppen in einer Organisation<br/>eine je vergebener Rolle"]
G["Gruppen im Realm<br/>Marke cias-managed"]
RR["Realm-Rollen"]
CR["Client-Rollen<br/>je Client"]
UP["User Profile<br/>welche Attribute es gibt"]
PM["Protocol Mapper<br/>Attribut → Claim, je Client"]
end
O --> OG
OG -. "trägt" .-> RR
OG -. "trägt" .-> CR
G -. "trägt" .-> RR
G -. "trägt" .-> CR
U -. "Mitglied" .-> O
U -. "Mitglied" .-> OG
U -. "Mitglied" .-> G
Jedes Kästchen steht für eine Art von Objekt im Realm. Die gestrichelten Linien zeigen, was woran hängt. Die folgenden Abschnitte gehen die Kästchen einzeln durch.
Wie sich CIAS anmeldet
Bevor der Adapter irgendetwas tut, holt er sich ein Token für sein Dienstkonto. Er hebt es auf und holt ein neues, kurz bevor es abläuft (30 Sekunden vorher).
Wann: client-secret ist gesetzt, username nicht.
CIAS meldet sich mit Client-ID und Geheimnis an (Client Credentials). Das Dienstkonto braucht Verwaltungsrechte: manage-users, view-users, query-users für Konten, manage-realm, view-realm, query-realms für Organisationen und manage-clients, view-clients, query-clients für Client-Rollen.
Ergebnis: der Weg für jede Installation
Wann: username und password sind gesetzt.
CIAS meldet sich als Person an (Password Grant), meist als Administrator im Realm master, den auth-realm nennt. Gedacht für Test-Realms, die gleich wieder verschwinden.
Ergebnis: Tests und Wegwerf-Realms
| Einstellung | Bedeutung |
|---|---|
codamai.cias.iam-provider | keycloak schaltet diesen Adapter ein |
codamai.cias.keycloak.server-url | Adresse von Keycloak, ohne Schrägstrich am Ende |
codamai.cias.keycloak.realm | der Realm, den CIAS verwaltet |
codamai.cias.keycloak.client-id | das Dienstkonto, als das sich CIAS anmeldet |
codamai.cias.keycloak.client-secret | sein Geheimnis |
codamai.cias.keycloak.username, password | stattdessen eine Person, nur für Tests |
codamai.cias.keycloak.auth-realm | wo das Token herkommt; ohne Angabe derselbe Realm |
codamai.cias.keycloak.password-setup-actions | welche Pflichtaktionen ein Passwort-Link verlangt; ohne Angabe nur UPDATE_PASSWORD. Erlaubt sind nur UPDATE_PASSWORD, UPDATE_PROFILE und TERMS_AND_CONDITIONS, und UPDATE_PASSWORD muss dabei sein, sonst startet CIAS nicht |
Fehlt die Adresse, der Realm, die Client-ID oder beides aus Geheimnis und Benutzername, startet die Anwendung nicht. Das eigenständige CIAS nimmt Adresse und Realm aus denselben Werten, mit denen es auch Tokens prüft. So verwaltet es immer den Keycloak, bei dem sich die Leute anmelden.
Konten
- Benutzername ist die E-Mail-Adresse. Keycloak verlangt einen Benutzernamen, also schreibt der Adapter die Adresse in beide Felder.
- Neue Konten sind gesperrt. Ein Konto entsteht mit „nicht freigeschaltet“ und „Adresse nicht bestätigt“. Die Adresse ist damit belegt, aber anmelden kann sich noch niemand. Siehe Ein Ablauf, vier Varianten.
- Suchen nach Adresse ignoriert Groß- und Kleinschreibung.
- Jede Änderung liest zuerst. Keycloak ersetzt beim Schreiben das ganze Konto. Der Adapter liest es deshalb, ändert genau ein Feld und schreibt es zurück. Sonst würde „freischalten“ nebenbei die Pflichtaktionen löschen, oder „Sprache setzen“ den Mandanten.
- Sperren setzt nur „nicht freigeschaltet“. Daten, Mitgliedschaften und Rollen bleiben. Siehe Sperren, entsperren, schließen.
- „Passwort setzen“ verlangen fügt die Pflichtaktion
UPDATE_PASSWORDhinzu, genau einmal, auch wenn der Aufruf wiederholt wird. - Attribute speichert Keycloak immer als Liste. Der Adapter schreibt einen Wert als Liste mit einem Eintrag und liest beim Zurücklesen den ersten Wert.
- Löschen gibt es nur zum Aufräumen, etwa für Konten, deren Registrierung nie bestätigt wurde. Ist das Konto schon weg, ist das kein Fehler.
Organisationen und Mitgliedschaften
Eine Organisation ist in Keycloak das Abbild eines dynamischen Mandanten. Ihr Alias ist genau der Mandantenschlüssel. Daran findet CIAS den Mandanten aus einem Token wieder.
- Anlegen: Der Adapter prüft vorher, ob der Alias schon vergeben ist, und meldet dann einen Konflikt. Zwei Organisationen mit einem Alias würden Mandanten verwechseln.
- Suchen läuft über den Alias (
q=alias:…), nicht über die Namenssuche. Die Namenssuche fände eine Organisation, deren Anzeigename den Schlüssel zufällig enthält. Aus dem Ergebnis nimmt der Adapter nur den exakten Treffer. - Mitgliedschaft geben und nehmen. Eine schon bestehende Mitgliedschaft noch einmal geben ändert nichts.
- Löschen gibt es nur zum Aufräumen. Ein Mandant, der endet, behält seine Organisation.
Wann CIAS eine Organisation anlegt, steht unter Einen Mandanten anlegen und bereitstellen.
Rollen global
Eine globale Rolle hängt direkt am Konto und gilt in jedem Mandanten.
- Realm-Rollen und Client-Rollen werden getrennt vergeben, jede über ihren eigenen Weg in Keycloak.
- Keycloak gibt jedem Konto die Sammelrolle
default-roles-<realm>. Der Adapter lässt sie beim Lesen weg. Sie ist keine fachliche Rolle. - Rollen anlegen: Client-Rollen legt der Abgleich an, weil ein Modul sie anmeldet. Realm-Rollen legt der Adapter nur an, wenn die Installation sie in ihrer Konfiguration nennt, nie auf Wunsch eines Moduls. Eine Rolle, die es schon gibt, bleibt unverändert, auch ihre Beschreibung.
- Beschreibung: Keycloak speichert höchstens 255 Zeichen. Eine längere Beschreibung kürzt der Adapter und hängt
…an. Im Rollenkatalog von CIAS bleibt sie vollständig.
Rollen in einer Organisation: Gruppen
Das ist der Teil, der am meisten überrascht. Eine Organisation in Keycloak hat keine Rollen. Sie hat Gruppen. Eine Rolle, die nur in einem Mandanten gilt, ist deshalb eine Gruppe in der Organisation, die diese Rolle trägt. Die Person ist Mitglied dieser Gruppe.
flowchart LR
P["Konto<br/>anna@nordbau.de"] -- "Mitglied" --> O["Organisation<br/>Alias nordbau"]
P -- "Mitglied" --> G1["Gruppe in nordbau<br/>cdms-backend:model-editor"]
P -- "Mitglied" --> G2["Gruppe in nordbau<br/>pruefer"]
G1 -. "trägt Client-Rolle" .-> C["cdms-backend / model-editor"]
G2 -. "trägt Realm-Rolle" .-> RR["pruefer"]
O --- G1
O --- G2
Der Name der Gruppe hängt von der Art der Rolle ab:
| Art der Rolle | Name der Gruppe in der Organisation | Beispiel |
|---|---|---|
| Client-Rolle | <client>:<rolle> | cdms-backend:model-editor |
| Realm-Rolle | <rolle> | pruefer |
Warum der Client im Namen steht: Zwei Module dürfen beide eine Rolle model-editor haben. Hieße die Gruppe nur model-editor, trüge sie beide Rollen, und wer die eine bekommt, bekäme die andere mit.
Wann: CIAS vergibt eine Rolle, die nur in diesem Mandanten gilt.
-
1CIAS→Keycloaksucht die Gruppe mit dem passenden Namen in der Organisation und legt sie an, falls sie fehlt
-
2CIAS→Keycloakhängt die Rolle an die Gruppe, über den eigenen Pfad der Organisation
-
3CIAS→Keycloaknimmt die Person in die Gruppe aufIst die Person nicht Mitglied der Organisation, lehnt Keycloak ab
-
4Keycloakdie Rolle steht ab dem nächsten Token im Claim
organizationErgebnis: Rolle gilt in diesem Mandanten
Wann: CIAS nimmt eine Rolle in einem Mandanten zurück.
Der Adapter nimmt die Person aus der Gruppe. Die Gruppe und ihre Rolle bleiben stehen, denn andere Personen im Mandanten sind vielleicht noch Mitglied. Die Mitgliedschaft in der Organisation bleibt ebenfalls. Gibt es die Gruppe nicht, gibt es nichts zu tun.
Ergebnis: Rolle weg, Person bleibt im Mandanten
Zwei Dinge in Keycloak müssen dafür stimmen:
- Gruppen in einer Organisation lassen sich nur über die Organisations-Schnittstelle ändern. Der gewöhnliche Weg für Gruppen lehnt sie ab. Der Adapter nutzt deshalb immer den Weg über die Organisation.
- Ins Token kommen diese Rollen nur, wenn der Client einen Mapper vom Typ
oidc-organization-group-membership-mappermitaddGroupRoleMappingshat. Ohne ihn sind die Rollen richtig vergeben, aber kein Token nennt sie. Der mitgelieferte Realm hat ihn. Siehe Was aus dem Token gelesen wird.
Diese Rollen stehen im Token nicht bei den globalen Rollen, sondern nur im Claim organization. Eine Organisation kann so nie zu den plattformweiten Rechten einer Person beitragen.
Gruppen im Realm
Die Gruppen von CIAS sind etwas anderes als die Gruppen in einer Organisation. Sie liegen im Realm, gelten plattformweit und tragen die Marke cias-managed. Der Adapter ändert, liest und löscht nur Gruppen mit dieser Marke. Gruppen in Organisationen fasst er über diesen Weg nie an. Wie das im Einzelnen läuft, steht unter Gruppen und Mitglieder verwalten und Abgleich mit Keycloak.
Profilattribute mit Rechten
Ein Attribut, das ein Modul anmeldet, legt der Adapter im User Profile an. Das ist ein einziges Dokument je Realm. Der Adapter liest es ganz, ändert nur die Einträge, um die es geht, und schreibt es ganz zurück. Alles andere darin bleibt, wie es war: die Felder, die Keycloak selbst mitbringt (Benutzername, E-Mail mit ihren Prüfregeln), und was ein Betreiber von Hand eingetragen hat.
Für jedes Attribut legt der Adapter vier Dinge fest:
| Feld im Profil | Was der Adapter schreibt |
|---|---|
multivalued | ob das Attribut eine Liste ist |
permissions | wer es sehen und wer es ändern darf, siehe unten |
defaultValue | der Wert für Konten, die älter sind als das Attribut, oder nichts |
required | nur, wenn eine Person es in einem Formular ausfüllen muss; dann roles: [user], nie für die Verwaltung |
Wann: Das Attribut beschreibt etwas, das die Installation festlegt, etwa tenant (der Mandant der Person).
view: [admin, user], edit: [admin]. Die Person sieht den Wert, ändern kann ihn nur die Verwaltung, also auch CIAS. Könnte eine Person ihren Mandanten selbst ändern, käme sie an die Daten eines anderen Kunden.
Ergebnis: nur CIAS und Administratoren schreiben
Wann: Das Attribut gehört der Person, etwa ihre Sprache. Das Modul meldet es als selbst änderbar an.
view: [admin, user], edit: [admin, user]. Die Person ändert es selbst, auch auf den Kontoseiten von Keycloak. Die Verwaltung darf es weiter korrigieren.
Ergebnis: die Person und CIAS schreiben
Der Adapter entfernt nie ein Attribut aus dem Profil. Meldet ein Modul ein Attribut nicht mehr an, bleibt es stehen, samt allen Werten an den Konten. Weicht ein Eintrag ab, etwa weil ein Attribut zur Liste wurde, korrigiert er genau die vier Felder oben. Siehe Attribute anmelden.
Claim-Zuordnungen
Ein Attribut im Profil landet noch in keinem Token. Dafür legt der Adapter am Client einen Protocol Mapper an: eine Regel, die ein Attribut des Kontos in einen Claim des Tokens kopiert.
- Typ
oidc-usermodel-attribute-mapper. - Mapper, Attribut und Claim tragen denselben Namen. Zwei Namen würden erlauben, in einen Claim zu schreiben, den niemand liest.
- Der Wert landet im ID-Token, im Access-Token, bei Userinfo und bei der Token-Prüfung (Introspection), als Text oder Liste von Texten.
- Gibt es den Mapper schon, aber mit anderen Einstellungen, korrigiert der Adapter ihn. Anders als bei der Beschreibung einer Rolle: Hier geht es darum, was im Token steht.
Mehr dazu unter Der Weg ins Token.
Wie Antworten von Keycloak übersetzt werden
| Keycloak antwortet | beim Lesen | beim Schreiben |
|---|---|---|
| 2xx | Ergebnis | erledigt |
| 404 | leeres Ergebnis | IamNotFoundException |
| 409 | – | IamConflictException |
| 5xx, Zeitüberschreitung, keine Verbindung | IamUnavailableException | IamUnavailableException |
| andere 4xx | IdentityProvisioningException | IdentityProvisioningException |
Wo ein Schreibzugriff zweimal kommen darf, gilt eine bestimmte Antwort als Erfolg: Ein 409 beim Anlegen einer Rolle, die gerade ein anderer Prozess angelegt hat, oder ein 404 beim Löschen von etwas, das schon weg ist.
Den Text einer Keycloak-Antwort übernimmt der Adapter nie in eine Fehlermeldung. Er kann Adressen oder Attributwerte enthalten.
Die Gesundheitsprüfung
Richtet der Starter den Adapter ein und ist Actuator dabei, meldet der Adapter unter dem Namen iam im Gesundheitsbericht, ob CIAS Keycloak benutzen kann. Er holt dafür ein Token für sein Dienstkonto und liest damit den Realm.
Wann: Token holen und Realm lesen gelingen.
Status UP, mit dem Namen des Realms.
Ergebnis: UP
Wann: Keycloak antwortet nicht, das Geheimnis wurde geändert, das Dienstkonto ist abgeschaltet oder der Realm umbenannt.
Status DOWN, mit dem Namen des Realms und nur der Art des Fehlers, nie seinem Text. Ein Fehlertext kann eine URL enthalten.
Ergebnis: DOWN
Das ist mehr als „läuft Keycloak?“. Ein Keycloak, der läuft, bei dem CIAS sich aber nicht mehr anmelden kann, würde erst bei der nächsten Registrierung auffallen.
Die Prüfung zählt nicht zur Bereitschaft (Readiness) der Anwendung. Ohne Keycloak kann CIAS noch vieles: Tokens prüfen braucht nur die öffentlichen Schlüssel, Mandanten lesen nur die Datenbank. Würde die Anwendung wegen Keycloak aus dem Verkehr genommen, würde aus einem teilweisen Ausfall ein ganzer.
Was Keycloak mitbringen muss
- Keycloak 26.7 oder neuer. Erst ab dieser Version haben Organisationen Gruppen mit Rollen.
- Die Funktion
organizationmuss am Server eingeschaltet sein (KC_FEATURES=organization, Einzahl) und im RealmorganizationsEnabled. - Das Dienstkonto mit den Rechten oben.
- Die Clients, deren Rollen CIAS vergibt. CIAS legt keinen Client an. Ein unbekannter Client ist ein
IamNotFoundException. - Der Mapper für Rollen in Organisationen an jedem Client, dessen Tokens CIAS liest.
Der Realm unter cias-runtime/deploy/keycloak erfüllt das alles und ist die Vorlage für einen eigenen.