Worum es geht
CIAS kann auf zwei Arten neben CDMS laufen. Fachlich ist das Ergebnis immer gleich: gleicher Code, gleiche Regeln, gleiche Ablehnungen. Anders ist nur, wie CDMS und CIAS miteinander reden.
Die zwei Bilder
flowchart LR
subgraph E["Eingebettet: ein Prozess"]
direction TB
E_CDMS["CDMS / Hub-Backend"]
E_CIAS["CIAS-Module<br/>(authentication, tenancy,<br/>user, authorization, …)"]
E_CDMS <-->|Methodenaufruf| E_CIAS
end
E_DB[("System-DB<br/>CDMS + CIAS-Tabellen")]
E --> E_DB
E --> KC1[(Keycloak)]
flowchart LR
subgraph G1["Dienst 1"]
G_CDMS["CDMS<br/>+ Filterkette<br/>+ Mandanten-Client"]
end
subgraph G2["Dienst 2"]
G_CIAS["CIAS-Dienst"]
end
G_CDMS -->|"HTTP: darf Mandant X<br/>bedient werden?"| G_CIAS
G_CIAS -->|"HTTP: GET /cias/fetch<br/>(Rollen, Attribute)"| G_CDMS
G_CDMS --> DB1[("System-DB CDMS<br/>+ Mandanten-DBs")]
G_CIAS --> DB2[("CIAS-DB")]
G_CDMS --> KC2[(Keycloak)]
G_CIAS --> KC2
Alle Unterschiede in einer Tabelle
| Eingebettet | Getrennt | |
|---|---|---|
| Prozesse | einer | zwei (oder mehr) |
| Was CDMS einbindet | die CIAS-Module direkt (mit oder ohne Starter) | nur die Filterkette und der Mandanten-Client von CIAS |
| Wie CDMS fragt: „Darf Mandant X bedient werden?“ | Methodenaufruf LocalTenantLookupAdapter | HTTP GET /cias/lookup/tenants/{key}, Zeitlimit 2 s |
| Mandantengebundene Attribute | Methodenaufruf in die Benutzerverwaltung von CIAS | HTTP GET /cias/lookup/users/{id}/attributes?tenantKey=… |
| Wie CIAS die Rollen von CDMS erfährt | als Bean im selben Prozess | CIAS ruft GET /cias/fetch bei CDMS auf, mit einer eigenen Realm-Leserolle (vorbelegt declaration-reader) |
| Datenbank von CIAS | die System-DB des Gastgebers; mit Starter je Modul eine eigene Migrationshistorie | eine eigene |
| Token, mit dem CDMS CIAS fragt | keines nötig | ein eigenes Dienst-Token, vom Dienst selbst bei Keycloak geholt, nie das Benutzer-Token |
| Token-Prüfung des Benutzers | die Filterkette im selben Prozess | die Filterkette im CDMS-Prozess, gegen Keycloak |
| CIAS fällt aus | fällt mit CDMS zusammen aus, es gibt kein „halb“ | bekannte Mandanten laufen aus dem Cache weiter, unbekannte werden abgelehnt |
| Mandant wird gesperrt | wirkt nach spätestens 30 s (Cache des Mandanten-Tors) | wirkt nach spätestens 30 s, aus Sicht jedes einzelnen Dienstes |
| Einstellung im Generator | das CIAS-Modul des Projekts läuft in der Runtime des Systems | das CIAS-Modul des Projekts läuft in einer anderen Runtime |
Eine Anfrage in beiden Betriebsarten
Dieselbe Anfrage „Liste der Kunden“ in beiden Welten:
Wann: CDMS und CIAS laufen im selben Prozess, z. B. das Hub-Backend.
sequenceDiagram
participant B as Browser/BFF
participant F as Filterkette (CIAS)
participant T as Mandanten-Tor (CIAS)
participant C as CDMS
participant DB as Mandanten-DB
B->>F: POST /crm/customer/query + Token
F->>F: Token prüfen, tauschen, Mandant auflösen
F->>T: darf "kunde-a" bedient werden?
Note over F,T: Methodenaufruf im selben Prozess
T-->>F: ja (30 s gemerkt)
F->>C: RequestContext gefüllt
C->>DB: SELECT … (nur erlaubte Zeilen)
DB-->>C: Zeilen
C-->>B: data + meta
Ergebnis: Ein Prozess, kein Netzwerkaufruf zwischen CDMS und CIAS.
Wann: CIAS läuft als eigener Dienst.
sequenceDiagram
participant B as Browser/BFF
participant F as Filterkette (in CDMS)
participant R as Mandanten-Client
participant S as CIAS-Dienst
participant C as CDMS
participant DB as Mandanten-DB
B->>F: POST /crm/customer/query + Token
F->>F: Token prüfen, tauschen, Mandant auflösen
F->>R: darf "kunde-a" bedient werden?
R->>S: GET /cias/lookup/tenants/kunde-a<br/>(Dienstkonto-Token)
S-->>R: served: true
R-->>F: ja (30 s gemerkt)
F->>C: RequestContext gefüllt
C->>DB: SELECT … (nur erlaubte Zeilen)
DB-->>C: Zeilen
C-->>B: data + meta
Ergebnis: Ein zusätzlicher HTTP-Aufruf, aber nur, wenn der Mandant nicht im Cache ist.
Was passiert, wenn CIAS nicht antwortet?
Nur im getrennten Betrieb kann CIAS allein ausfallen. Dann entscheidet das Gedächtnis des Mandanten-Tors:
| CIAS antwortet? | Mandant im Cache? | Ergebnis für die Anfrage |
|---|---|---|
| ja | – | CIAS entscheidet, Antwort wird 30 s gemerkt |
| nein | ja | letzte bekannte Antwort gilt weiter |
| nein | nein | 403 tenant-not-served – im Zweifel ablehnen |
Ein 403 vom Lookup oder eine Zeitüberschreitung zählt dabei als Fehler, nicht als „nein“. Der Cache ist deshalb ein Verfügbarkeitspuffer, kein Geschwindigkeitstrick.
Warum beide Arten fachlich gleich sein müssen
-
1CIASKeine CIAS-Klasse aktiviert sich selbst. Jedes Modul ist hinter einem Schalter
codamai.cias.<modul>.enabledohne StandardwertSonst würde CDMS, das allecom.codamai-Klassen scannt, CIAS in jeder Anwendung einschalten, die nur das Jar mitbringt. -
2CIASEingebettet und getrennt laufen derselbe Code mit denselben Regeln und Ablehnungen
-
3CIASGetauscht werden nur die Adapter – Mandanten-Lookup, Attribut-Lookup und Deklaration, lokal oder über HTTP, dazu der Adapter zum Identity ProviderErgebnis: Ein Fehler, der nur in einer Betriebsart auftritt, ist per Definition ein Fehler
Und CRMS?
CRMS kennt dieselben zwei Bauformen, und der Hub leitet sie genauso aus der Laufzeit des CRMS-Moduls ab. Die Entscheidung fällt aber getrennt von der für CIAS. Für CRMS sieht der Vergleich so aus:
| CRMS eingebettet | CRMS als eigener Dienst | |
|---|---|---|
| Was die CDMS-Anwendung einbindet | Starter, die Dokumentablage, die Formatmodule und die HTTP-Schnittstelle von CRMS | Starter und crms-client |
| Wie CDMS CRMS ruft | Methodenaufruf ReportRenderPort | HTTP POST /crms/render |
| Token | keines nötig | das Token der Person, nie ein Dienst-Token |
| Datenbank | die der Anwendung | eine eigene |
| Ankerlauf und Aufbewahrung | in der Anwendung | im CRMS-Dienst |
Die Kombinationen mit CIAS stehen unter CRMS in den Betriebsarten.
Weiter
- CIAS eingebettet (eine Einheit): welche Module ein Gastgeber einbindet und wie er sie verdrahtet
- CIAS als eigener Service: welche Aufrufe über HTTP gehen und mit welchem Token
- Warum beide Betriebsarten fachlich gleich sind
- Was eingestellt wird und SINGLE oder MULTI
- CRMS in den Betriebsarten