CodamAIDocs
Themafertig

Was läuft, bestimmt die Konfiguration

Jedes CIAS-Modul ist hinter einem Schalter ohne Standardwert. Warum keine CIAS-Klasse sich selbst aktiviert und was im Build entschieden wird (welcher Provider-Adapter).

Ausprägungen
Modul anModul ausSchalter fehlt → Start scheitertGenerator: EMBEDDED / REMOTE / NONE

Worum es geht

CIAS ist keine Anwendung, die man startet, sondern eine Sammlung von Jars. Ein Jar ist eine Bibliothek, die im Klassenpfad einer Anwendung liegt. Ob ein CIAS-Modul in dieser Anwendung tatsächlich arbeitet, entscheidet allein die Konfiguration. Dass das Jar da ist, reicht nicht.

Warum kein Modul sich selbst einschaltet

Spring findet Klassen normalerweise über einen Komponentenscan: Es durchsucht Pakete nach Klassen mit Markierungen wie @Service oder @Component und baut sie zusammen. CDMS scannt dabei alles unter com.codamai — und CIAS liegt unter com.codamai.

Trüge eine CIAS-Klasse so eine Markierung, würde jede CDMS-Anwendung sie einsammeln, sobald das Jar irgendwie im Klassenpfad landet, etwa als Abhängigkeit einer Abhängigkeit. Zusammengesteckt würde sie dann mit Objekten, die es dort gar nicht gibt.

Deshalb:

Wie ein CIAS-Modul in eine Anwendung kommt
  1. 1
    Build
    legt das Jar in den Klassenpfad
    Keine Klasse darin trägt @Service, @Repository oder @Component. Der Komponentenscan findet nichts.
  2. 2
    CIAS
    eine Konfigurationsklasse je Modul registriert die Objekte ausdrücklich
    Der Starter meldet seine Konfigurationen zusätzlich als Auto-Konfiguration an. Auto-Konfigurationen nimmt Spring absichtlich vom Scan aus — auch das ist Schutz gegen die versehentliche Einbindung.
  3. 3
    CIAS
    liest den Schalter des Moduls
  4. 4
    CIAS
    Schalter steht nicht auf true → das Modul arbeitet nicht
  5. 5
    CIAS
    Schalter steht auf true → das Modul arbeitet
    Ergebnis: Ein Modul ist an, weil jemand es hingeschrieben hat, nie weil ein Jar mitgekommen ist.

Die Schalter

Das Bild zeigt, wo die Schalter sitzen. Links das, was immer da ist, sobald die Filterkette läuft; rechts die Module, die einzeln zugeschaltet werden.

flowchart LR
    subgraph P["Ein Prozess"]
        direction TB
        A["Filterkette, Mandanten-Tor<br/><i>kein Schalter: da oder nicht da</i>"]
        L{"codamai.cias.tenancy.lookup"}
        A --> L
        L -->|local| T["Mandantenverwaltung<br/>codamai.cias.tenancy.enabled"]
        L -->|remote| C["Mandanten-Client<br/>+ client.base-url, client.credentials"]
        A -.-> U["Benutzerverwaltung<br/>codamai.cias.user.enabled"]
        A -.-> Z["Rollenverwaltung<br/>codamai.cias.authorization.enabled"]
        A -.-> R["Registrierung<br/>codamai.cias.registration.enabled"]
        A -.-> N["Mailversand<br/>codamai.cias.notification.enabled"]
        A -.-> AU["Audit<br/>codamai.cias.audit.enabled"]
    end
    IP{"codamai.cias.iam-provider"}
    Z --> IP
    U --> IP
    IP -->|keycloak| K[(Keycloak)]

Die vollständige Liste:

SchalterWofürWerte
codamai.cias.tenancy.enabledMandanten führen: anlegen, sperren, schließentrue
codamai.cias.tenancy.lookupwoher das Mandanten-Tor seine Antwort holtlocal oder remote
codamai.cias.tenancy.client.base-urlwo CIAS erreichbar istnur bei lookup: remote
codamai.cias.tenancy.client.credentials.*der eigene Client beim IAM, mit dem das Dienst-Token geholt wird (token-uri, client-id, client-secret); ohne ihn ein festes .tokennur bei lookup: remote
codamai.cias.tenancy.restdie Verwaltungs-API /cias/admin/tenantstrue / false
codamai.cias.tenancy.lookup-restder Endpunkt, den andere Dienste fragentrue / false; im eigenständigen CIAS-Dienst true
codamai.cias.tenancy.lookup-roleswer diesen Endpunkt fragen darfRollennamen
codamai.cias.user.enabled, .restder Benutzerdatensatz und seine APItrue / false
codamai.cias.user.lookup-rest, .lookup-rolesAttributwerte pro Mandant für andere Dienstetrue / false (im eigenständigen CIAS-Dienst true), Rollennamen
codamai.cias.authorization.enabled, .restRollenkatalog, Vergaben, Abgleich mit Keycloaktrue / false
codamai.cias.registration.enabled, .restRegistrierung und Einladungtrue / false
codamai.cias.notification.enabled, .restMailvorlagen und ihre Bearbeitungtrue / false
codamai.cias.notification.editor-roleswer jede Mailvorlage ändern darf, auch per CIAS_NOTIFICATION_EDITOR_ROLESStandard platform-admin,mail-template-admin
codamai.cias.notification.mail, .mail.fromwie Mails das Haus verlassensmtp oder log
codamai.cias.audit.enableddie Audit-Spurtrue / false
codamai.cias.<modul>.persistencewie das Modul an die Datenbank kommtjpa
codamai.cias.iam-providermit welchem Identity Provider CIAS sprichtkeycloak oder memory
codamai.cias.migration.enabledlegt die Tabellen von CIAS an und hebt sie antrue / false
codamai.cias.platform-administrator-roleswelche Rollen die Plattform verwaltenRollennamen, leer heißt niemand
codamai.cdms.cias.reader-roleswer in CDMS GET /cias/fetch lesen darfRollennamen
codamai.persistence.tenant.modedie Betriebsart der DatenhaltungSINGLE oder MULTI

Die Filterkette hat keinen eigenen Schalter. Sie prüft jedes Token, und sie arbeitet, sobald ihr Jar da ist. Was sie braucht, ist kein Schalter, sondern eine Antwort: codamai.cias.tenancy.lookup sagt ihr, wen sie nach dem Mandanten fragt.

Die drei Ausprägungen

Was ein Schalter bewirkt

Wann: Der Schalter steht auf true.

  1. 1
    CIAS
    baut die Objekte des Moduls zusammen
  2. 2
    CIAS
    die Endpunkte des Moduls antworten, die Abläufe laufen

Ergebnis: Das Modul arbeitet.

Wann: Der Schalter fehlt oder steht auf false.

„Aus“ sieht je nach Modul verschieden aus, und beides ist Absicht. Bei tenancy und audit entscheidet der Schalter, ob die Objekte überhaupt entstehen: Sie sind dann nicht da. Bei user, authorization, registration und notification entstehen die Objekte immer, und der Schalter wird dort gelesen, wo er etwas entscheidet: Der Ablauf ist dann eine Ausführung, die jeden Aufruf verweigert, und die Endpunkte antworten 404, bevor überhaupt ein Controller erreicht wird.

Ergebnis: In beiden Fällen passiert fachlich nichts. Nach außen ist der Unterschied nur, ob ein Endpunkt 404 sagt oder gar nicht erst existiert.

Wann: Eine Angabe fehlt, ohne die CIAS raten müsste.

  1. 1
    CIAS
    findet die Angabe nicht; einen Standardwert gibt es absichtlich nicht
  2. 2
    CIAS
    bricht den Start ab, die Meldung nennt die Einstellung oder den Typ

Ergebnis: Die Anwendung kommt nicht hoch. Das ist besser als eine, die großzügig hochkommt.

Wann welcher Fall gilt, ist nicht Geschmackssache. Es hängt davon ab, was ein falscher Standardwert anrichten würde:

Warum manche Angabe den Start abbricht
Was fehltFolge
codamai.cias.tenancy.lookupStart scheitert. Ohne diese Angabe gibt es niemanden, der das Mandanten-Tor beantwortet — und ein Tor, das ohne Antwort jeden durchlässt, wäre ein Loch aus einer vergessenen Zeile.
client.base-url bei lookup: remoteStart scheitert. Eine erfundene Adresse wäre schlimmer als keine.
codamai.cias.iam-provider, wo die Module ihn brauchenStart scheitert. Ein CIAS ohne Identity Provider nähme Registrierungen an, die es nie ausführen kann.
codamai.persistence.tenant.mode, wo es CDMS-Persistenz gibtStart scheitert. Ein Standardwert würde still eine Mandantentrennung abschalten oder eine erfinden.
codamai.cias.notification.mail, wenn das Mailmodul an istStart scheitert. Der Standard log würde jede Mail als verschickt melden und keine zustellen.
codamai.cias.user.enabledKein Fehler. Das Modul ist aus, und eine Installation ohne Benutzerverwaltung ist ein gültiger Zustand.
codamai.cias.tenant-gate.ttl und andere ZeitenKein Fehler. Sie haben Standardwerte, denn ein falscher Wert macht die Anwendung träger, öffnet aber nichts.

Die ganze Regel dahinter steht unter Im Zweifel ablehnen, samt der Liste aller Pflicht-Angaben.

Was die Anwendung selbst beisteuern muss

Manche Angaben sind keine Zeile in einer Datei, sondern Beans. Eine Bean ist ein Objekt, das Spring beim Start zusammensteckt.

BeanWas sie entscheidetLiefert CIAS eine mit?
PlatformAdministratorswelche Rollen die Plattform verwaltennein, und das bleibt so: eine Bibliothek darf keine Administratorrolle erfinden
RegistrationRoleswelche Rollen eine Registrierung vergibtnein
MailTemplateEditPolicywelche Mails Mandanten-Administratoren umschreiben dürfen; die Editor-Rollen liest sie aus CIAS_NOTIFICATION_EDITOR_ROLESnein
ManagedTypesContributiondass die Tabellen von CIAS in der Persistenz des Gastgebers bekannt sindnein, das weiß nur der Gastgeber
CallerContextProviderwoher CIAS erfährt, wer gerade handeltder Starter bringt eine mit, die auf den RequestContext schaut; ohne Starter legst du sie selbst an
Clockdie Zeitquellewie oben

Fehlt eine davon, wo sie gebraucht wird, scheitert der Start mit dem Namen des Typs in der Meldung.

Was im Build entschieden wird

Ein Teil der Entscheidung fällt früher, nämlich wenn der Projektrahmen erzeugt wird. Ein Feld dafür gibt es nicht. Der Generator leitet die Einbindung aus zwei Angaben im Hub ab: ob das System über CIAS anmeldet (authentication) und in welcher Runtime das CIAS-Modul des Projekts läuft.

authenticationCIAS-Modul des ProjektsErgebnis
NONEwird nicht angesehenNONE, öffentliches System
OIDCläuft in der Runtime dieses SystemsEMBEDDED
OIDCläuft in einer anderen Runtime, als eigener Dienst oder eingebettet in ein anderes CDMS-Modul des ProjektsREMOTE, dieses System ist Client
OIDCist keiner Runtime zugeordnetder Build wird abgelehnt
OIDCdas Projekt hat keinsder Build wird abgelehnt

Ein abgelehnter Build antwortet mit 400, und die Meldung nennt, was zu modellieren ist: dem Projekt ein CIAS-Modul geben, es in eine Runtime setzen oder authentication auf NONE stellen.

Die drei Einbindungen im Build
NONEREMOTEEMBEDDED
Was sie bedeutetDie Anwendung meldet niemanden über CIAS an.CIAS läuft in einer anderen Runtime.CIAS läuft in diesem Prozess.
Welche Jars dazukommender Baustein für den offenen Zugang von CDMS, kein CIAS-Jardie Filterkette und der Mandanten-Client von CIASdie Filterkette, die Mandanten-, Benutzer- und Rollenverwaltung von CIAS, der Keycloak-Adapter, der Starter
Was der Generator schreibtden Schalter für den offenen Zugangcodamai.cias.tenancy.lookup: remote in der application.yamldie Konfigurationsklassen, den codamai.cias-Block der application.yaml und bei jedem Build die cias-configuration.yaml aus dem CIAS-Modul
Welche Umgebungsvariablen dazukommenCODAMAI_CDMS_OPEN_ACCESS_ALLOWED_NETWORKSdie Anmelde-Variablen (CIAS_ISSUER, CIAS_CLIENT …) und CODAMAI_CIAS_TENANCY_CLIENT_BASE_URL mit den Zugangsdaten des Clientsdie Anmelde-Variablen und die des eingebetteten CIAS: Verwaltungs-Client, Benutzer, Rollen, Registrierung, Mail, Audit
Wer das Mandanten-Tor beantwortetniemand, es gibt keine Filterkette von CIASder CIAS-Dienst, über HTTPdie Mandantenverwaltung von CIAS im selben Prozess, als Methodenaufruf

Zwei Dinge daran sind leicht zu übersehen:

  • Die Einbindung kann für zwei CDMS-Module desselben Projekts verschieden sein. Läuft das CIAS-Modul in der Runtime des einen, ist es dort eingebettet, und das andere in seiner eigenen Runtime ist sein Client. Einen eigenen CIAS-Dienst braucht das zweite dafür nicht.
  • Bei EMBEDDED entscheidet das CIAS-Modul, was eingeschaltet ist. Die application.yaml des Rahmens lässt Benutzer, Rollen und Keycloak-Zugriff aus. Die erzeugte cias-configuration.yaml setzt sie auf das, was am CIAS-Modul im Hub eingestellt ist. Eine Umgebungsvariable wie CIAS_USER überschreibt beides. Auch hier gilt: Was läuft, bestimmt die Konfiguration, nicht der Klassenpfad.

Fallen

Weiter

Suchen