Mandantenverwaltung
Mandanten trennen Organisationen (z. B. verschiedene Hilfsorganisationen oder Kreisverbände) vollständig voneinander — eigene Benutzer, eigene Einsätze, eigene Daten. Die Mandantenverwaltung legt neue Mandanten an und verbindet sie mit einem Hostnamen für die automatische Anmeldung.
Config.License.MultiTenant)
aktiviert ist und der angemeldete Benutzer die Rolle
global_admin besitzt. Ohne Multi-Mandant-Lizenz registriert der
Router die zugehörigen Routen gar nicht erst — weder der Menüpunkt
Einstellungen → Mandanten noch /tenant/list sind dann
erreichbar (404). Diese Doku-Seite und ihre Screenshots wurden gegen eine
Demo-Lizenz mit aktiviertem Multi-Mandant-Feature erstellt.
Mandantenliste
Route: GET /tenant/list · Menüpfad: Einstellungen → Mandanten
Die Tabelle zeigt alle Mandanten mit Name, Beschreibung, hinterlegtem Hostnamen und
Erstellungsdatum. Ganz oben erscheint stets der interne System-Mandant
(technischer Mandant für global_admin-Konten ohne eigene Organisation —
ohne eigenen Hostnamen).
Optionen je Zeile
- →✏️ Bearbeiten — öffnet das Formular vorbefüllt (siehe Mandant anlegen/bearbeiten).
- →🗑️ Löschen — mit Bestätigungsdialog, siehe Mandant löschen.
- →↪ In Mandant wechseln — siehe In Mandant wechseln.
global_admin
stets der Name des aktuell aktiven Mandanten (z. B. „System") neben
dem eigenen Benutzernamen — so ist immer auf den ersten Blick erkennbar, in welchem
Mandantenkontext man sich gerade befindet.
Mandant anlegen / bearbeiten
Menüpfad: Mandanten → Hinzufügen bzw. ✏️-Schaltfläche in der Tabelle
Das Formular erscheint als Dialog mit drei Feldern. Nur Name ist Pflichtfeld.
Formularfelder
- Name Pflichtfeld — Anzeigename des Mandanten (max. 128 Zeichen), z. B. „DRK Demo". Wird u. a. beim Anmelden als Mandantenname eingegeben, wenn keine Hostname-Erkennung greift.
- Beschreibung (optional, max. 512 Zeichen) — interner Hinweistext, z. B. die Organisation im Klartext.
- Hostname (optional) — der Domainname, über den dieser Mandant automatisch erkannt werden soll, z. B.
demo-drk.localodereinsatz.drk-kreisverband.deim Produktivbetrieb. Wird auf gültige Hostname-Syntax geprüft (validate.Hostname).
Schritt für Schritt
- Schaltfläche Hinzufügen anklicken (oder ✏️ bei einem bestehenden Mandanten).
- Name eingeben, optional Beschreibung und Hostname ergänzen.
- Speichern — der Mandant erscheint sofort in der Liste, zunächst ohne eigene Benutzer.
- Anschließend für den neuen Mandanten über die Benutzerverwaltung mindestens einen Administrator-Benutzer anlegen (dafür zunächst über In Mandant wechseln in dessen Kontext wechseln).
httputil.GetTenantUploadDir), in dem mandantenspezifische Dateien
(z. B. Anhänge im Stab-Modul) getrennt von anderen Mandanten abgelegt werden.
Wie das Hostname-Routing funktioniert
Hintergrund zum Feld Hostname
Der Hostname eines Mandanten ist die Grundlage für eine reibungslose Anmeldung im Mehrmandantenbetrieb: Statt dass jeder Benutzer seinen Mandantennamen von Hand eingibt, erkennt rk den Mandanten automatisch daran, unter welcher Adresse die Seite aufgerufen wurde.
Ablauf bei jedem Aufruf
- Der Browser sendet den aufgerufenen Hostnamen im Host-Header mit (z. B.
demo-drk.local, ggf. mit Port wiedemo-drk.local:8443). tenantFromHostname()entfernt einen eventuell vorhandenen Port und sucht in der Mandantenliste nach einer exakten Übereinstimmung mit dem Feld Hostname.- Gibt es einen Treffer (und ist es nicht der interne System-Mandant), wird dieser Mandant für die aktuelle Anfrage verwendet — auf der Anmeldeseite erscheint sein Name statt des Eingabefelds.
- Gibt es keinen Treffer (z. B. Aufruf über
localhostin der Entwicklung, oder ein noch nicht zugeordneter Hostname), wird das Mandantenfeld eingeblendet und der Benutzer muss den Mandantennamen selbst eingeben.
Voraussetzungen im Betrieb
-
→
Der Hostname muss als DNS-Eintrag auf den rk-Server zeigen und im Reverse-Proxy (siehe
server/deployment/nginx.conf) korrekt durchgereicht werden — rk selbst registriert keine DNS-Einträge. -
→
Hinter einem Reverse-Proxy muss dieser den Host-Header unverändert weiterleiten, damit
r.Hostim Server den vom Browser aufgerufenen Namen enthält und nicht etwa den internen Proxy-Zielnamen. -
→
Für Cookie-Sicherheit (Attribut
Secure) wird zusätzlich erkannt, ob die Anfrage tatsächlich über HTTPS ankam — entweder direkt oder über einen vertrauenswürdigen Proxy viaX-Forwarded-Proto. Diese Unterscheidung war Gegenstand eines Bugfixes (siehe Hintergrund unten) und ist unabhängig vom Hostname-zu-Mandant-Abgleich selbst.
Secure-Attributs des
Session-Cookies und des Schemas (http/https) in
Passwort-Reset-Links: Beide hingen zuvor direkt an einer statischen
Konfigurationseinstellung (h.Config.SecureCookies) statt die tatsächliche
Anfrage zu berücksichtigen. Hinter einem Reverse-Proxy mit TLS-Terminierung führte das
dazu, dass Anmeldungen über einen mandantenspezifischen Hostnamen fehlschlagen konnten.
Die Korrektur führte die Hilfsfunktion httputil.IsSecureRequest(r, h.Config)
ein, die X-Forwarded-Proto bzw. r.TLS der jeweiligen Anfrage
auswertet, statt sich allein auf eine globale Einstellung zu verlassen.
In Mandant wechseln
Route: GET /tenant/{id}/switch · ↪-Schaltfläche in der Mandantenliste
Ein global_admin kann ohne erneute Anmeldung zwischen Mandanten
wechseln, um z. B. im Rahmen des Supports die Sicht eines bestimmten Mandanten
einzunehmen — etwa um dort selbst einen ersten Administrator-Benutzer anzulegen.
Was beim Wechseln passiert
- →Es wird ausschließlich der aktive Mandant der bestehenden Sitzung umgeschaltet (
active_tenant_idauftbl_user_sessions) — es findet keine erneute Anmeldung statt. - →Anschließend zeigen alle mandantengebundenen Ansichten (Einsätze, Benutzer, …) automatisch die Daten des neu gewählten Mandanten.
- →Der Wechsel ist jederzeit reversibel — einfach erneut über die Mandantenliste einen anderen Mandanten (z. B. wieder „System") wählen.
global_admin
gedacht und sollte mit Bedacht eingesetzt werden — alle Aktionen, die danach
ausgeführt werden (z. B. Benutzer anlegen), wirken sich auf den gewählten
Mandanten aus, nicht mehr auf „System".
Mandant löschen
Route: POST /tenant/{id}/delete · 🗑️-Schaltfläche in der Mandantenliste
Vor dem endgültigen Entfernen erscheint zunächst ein Bestätigungsdialog „Mandant wirklich löschen?". Wie bei Benutzern handelt es sich um einen Soft-Delete — der Mandant verschwindet aus der Liste, seine Daten (Einsätze, Benutzer, hochgeladene Dateien) bleiben in der Datenbank erhalten, sind aber über die Anwendung nicht mehr erreichbar.