Wer als Unternehmen mehrere interne Anwendungen gleichzeitig betreibt, etwa ein Admin-Panel für die Produktverwaltung, ein Grafana-Dashboard für das Monitoring und ein internes Ticket-System, verwaltet über kurz oder lang auch mehrere getrennte Benutzerdatenbanken. Jede Anwendung bringt ihr eigenes Login mit, ihren eigenen Passwort-Reset-Prozess und ihre eigene Liste an Konten. Verlässt eine Person das Unternehmen, muss das Betriebsteam den Zugriff in jeder einzelnen Anwendung von Hand entziehen, und ein vergessenes Konto bleibt oft monatelang unbemerkt aktiv. Bei zehn oder zwanzig internen Werkzeugen wächst dieses Problem nicht in gleichem Tempo weiter, sondern mit jeder neuen Anwendung ein Stück schneller.
Keycloak ist ein quelloffener Server für Identity- und Access-Management (IAM), also für die zentrale Verwaltung von Benutzerkonten, Anmeldedaten und Zugriffsrechten. Die Software entstand ursprünglich im Umfeld von Red Hat und JBoss und wird heute als Projekt der Cloud Native Computing Foundation (CNCF) weiterentwickelt, dort seit April 2023 im Reifegrad Incubating und damit noch nicht im höchsten CNCF-Status Graduated. Keycloak setzt die offenen Standards OpenID Connect, OAuth2 und SAML um, sodass jede angebundene Anwendung den Login an genau einen gemeinsamen Keycloak-Server delegieren kann, statt eine eigene Authentifizierung selbst zu programmieren. Für das Betriebsteam heißt das in der Praxis: Benutzerkonten liegen an einem Ort, Gruppen und Rollen liegen ebenfalls an einem Ort, und ein einziger Klick sperrt den Zugriff einer Person auf jede angebundene Anwendung gleichzeitig.
Systemvoraussetzungen
Der Aufbau eines gemeinsamen Keycloak-Realms für mehrere interne Anwendungen braucht wenige, aber aktuelle Bausteine. Die folgende Tabelle nennt sie und wofür sie im Ablauf stehen.
| Komponente | Version oder Anforderung | Zweck |
|---|---|---|
| Keycloak-Server | Docker-Image quay.io/keycloak/keycloak, aktuell Hauptversion 26 (Stand 26.7) | Identity- und Access-Management-Server, der Login, Token-Ausstellung und Benutzerverwaltung übernimmt |
| Docker Engine | Ab Version 20.10, mit Docker Compose | Betrieb von Keycloak und der Datenbank als Container |
| Produktionsdatenbank | PostgreSQL (empfohlen), alternativ MySQL, MariaDB, Oracle Database oder Microsoft SQL Server | Dauerhafte Speicherung von Realms, Benutzern, Clients und Sessions; ersetzt die eingebaute Entwicklerdatenbank dev-file |
| Initialer Administrator-Zugang | Umgebungsvariablen KC_BOOTSTRAP_ADMIN_USERNAME und KC_BOOTSTRAP_ADMIN_PASSWORD | Einmaliges Anlegen des ersten Admin-Kontos beim ersten Start des leeren Servers |
| Erreichbare Domain mit TLS | Eigene Subdomain, zum Beispiel auth.beispiel-firma.de, mit gültigem TLS-Zertifikat | Gemeinsamer Endpunkt, den jede angebundene Anwendung für Login und Token-Austausch anspricht |
| Registrierter Client je Anwendung | OpenID-Connect-fähige Anwendung mit fester Redirect-URI | Jede interne Anwendung, die den Login an Keycloak delegieren soll, braucht einen eigenen Eintrag im Realm |
Systemarchitektur
Ein Realm ist in Keycloak ein abgeschlossener Verwaltungsbereich für Benutzer, Gruppen, Rollen und Clients; Realms sind vollständig voneinander isoliert, sodass ein Konto im einen Realm im anderen völlig unbekannt bleibt. Ein Client ist der Eintrag, mit dem sich eine einzelne Anwendung im Realm registriert und der ihr erlaubt, Anmeldungen über diesen Realm abzuwickeln. Rollen und Gruppen legen danach fest, wer nach dem Login worauf zugreifen darf: Realm-Rollen gelten realmweit über alle Clients hinweg, Client-Rollen gelten nur innerhalb einer einzelnen Anwendung, und eine Gruppe bündelt beides für mehrere Benutzer gleichzeitig.
flowchart TD
ADM[Administrator deaktiviert ein Benutzerkonto] --> KC[Keycloak Realm mit Benutzern Gruppen und Rollen]
A[Browser eines Mitarbeitenden] --> B1[Anwendung 1 als Client]
A --> B2[Anwendung 2 als Client]
A --> B3[Anwendung 3 als Client]
B1 --> KC
B2 --> KC
B3 --> KC
KC --> DB[Postgres Datenbank fuer Realms Benutzer und Sessions]
KC --> TOK[Ausstellung von Zugriffstoken und Refresh Token]
TOK --> B1
TOK --> B2
TOK --> B3
Der Ablauf läuft für jede Anwendung im Realm gleich. Der Browser eines Mitarbeitenden ruft eine interne Anwendung auf, und diese Anwendung leitet unangemeldete Nutzer zum gemeinsamen Keycloak-Realm weiter, statt selbst nach einem Passwort zu fragen. Keycloak prüft die eingegebenen Zugangsdaten gegen die im Realm gespeicherten Benutzerkonten und stellt bei Erfolg zwei Token aus: ein kurzlebiges Zugriffstoken (Access Token), das die Anwendung bei jeder Anfrage mitschickt, und ein länger gültiges Refresh-Token, mit dem die Anwendung ein neues Zugriffstoken anfordert, ohne den Nutzer erneut nach einem Passwort zu fragen. Jede angebundene Anwendung prüft das Zugriffstoken anhand seiner digitalen Signatur selbst und muss dafür nicht bei jeder einzelnen Anfrage bei Keycloak nachfragen.
Deaktiviert ein Administrator ein Benutzerkonto im Realm, kann sich diese Person bei keiner der angebundenen Anwendungen mehr neu anmelden und erhält auch über ihr Refresh-Token kein neues Zugriffstoken mehr. Ein bereits ausgestelltes Zugriffstoken bleibt davon zunächst unberührt. Weil es sich um ein signiertes, in sich geschlossenes JSON Web Token (JWT) handelt, prüft die empfangende Anwendung nur die Signatur und das eingebaute Ablaufdatum, nicht den aktuellen Kontostatus in Keycloak. Nach der offiziellen Keycloak-Dokumentation zur Sitzungsverwaltung widerruft selbst die Funktion "Sign out all active sessions" im Admin-Bereich keine bereits ausgestellten Zugriffstoken; diese müssen stattdessen regulär ablaufen. Wer die Lücke zwischen Deaktivierung und tatsächlichem Zugriffsende kurz halten will, setzt deshalb die Gültigkeitsdauer des Zugriffstokens realmweit auf wenige Minuten und verlässt sich für alles Langlebige auf das Refresh-Token, das Keycloak beim Deaktivieren sofort sperrt.
Schritt-für-Schritt-Umsetzung
Keycloak mit Docker Compose und einer Postgres-Datenbank starten
Für den produktiven Betrieb braucht Keycloak eine externe Datenbank statt der eingebauten Entwicklerdatenbank dev-file, die laut Keycloak-Dokumentation ausdrücklich nicht für den Produktivbetrieb geeignet ist. Die folgende Docker-Compose-Datei startet Keycloak zusammen mit einer PostgreSQL-Datenbank und setzt die Umgebungsvariablen für das erste Administrator-Konto.
services:
postgres:
image: postgres:17
container_name: keycloak-postgres
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: aendern-vor-produktivstart
volumes:
- ./pgdata:/var/lib/postgresql/data
restart: unless-stopped
keycloak:
image: quay.io/keycloak/keycloak:26.7
container_name: keycloak
command: start --optimized
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: aendern-vor-produktivstart
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: aendern-vor-produktivstart
KC_HOSTNAME: auth.beispiel-firma.de
KC_PROXY_HEADERS: xforwarded
depends_on:
- postgres
ports:
- "8080:8080"
restart: unless-stopped
Der Parameter KC_HOSTNAME legt fest, unter welcher Adresse Keycloak sich selbst gegenüber allen Clients bekannt macht, unabhängig davon, hinter wie vielen internen Netzwerkschichten der Container tatsächlich läuft. Läuft vor Keycloak ein Reverse Proxy, der TLS terminiert, sorgt KC_PROXY_HEADERS dafür, dass Keycloak die tatsächliche Herkunftsadresse aus den vom Proxy gesetzten Kopfzeilen liest, statt sich selbst als unverschlüsselten Endpunkt zu behandeln.
Eine zweite Anwendung als Client im Realm registrieren
Nach dem ersten Start meldet sich ein Administrator über die Adresse des Servers an der Admin-Konsole an und legt zunächst einen neuen Realm an, etwa mit dem Namen firma-intern, statt den mitgelieferten Realm master für den laufenden Betrieb zu verwenden. Jede weitere interne Anwendung bekommt danach einen eigenen Client-Eintrag in diesem Realm.
Clients auswählen. Im linken Menü des Realms auf "Clients" klicken und danach auf "Create client".
Client-Grunddaten eintragen. Als "Client type" den Wert "OpenID Connect" wählen und im Feld "Client ID" einen eindeutigen Namen für die Anwendung eintragen, zum Beispiel
grafana-intern.Client authentication aktivieren. Für eine serverseitige Anwendung den Schalter "Client authentication" einschalten; Keycloak erzeugt dadurch ein Client Secret, ein gemeinsames Geheimnis zwischen Anwendung und Keycloak. Für eine reine Browser-Anwendung ohne eigenen Server bleibt der Schalter aus, der Client gilt dann als public.
Redirect-URI und Web Origins eintragen. Unter "Valid redirect URIs" die genaue Adresse eintragen, an die Keycloak nach dem Login zurückleiten darf, etwa
https://tool.beispiel-firma.de/api/auth/callback/keycloak, und unter "Web origins" die Domain der Anwendung für Cross-Origin-Anfragen freigeben.Speichern und Secret übernehmen. Nach dem Speichern zeigt der Reiter "Credentials" das erzeugte Client Secret, das zusammen mit der Client ID in die Konfiguration der Anwendung übernommen wird.
Damit die neue Anwendung nicht nur Logins entgegennimmt, sondern nach dem Login auch weiß, wer worauf zugreifen darf, bekommt sie zusätzlich passende Rollen zugewiesen: eine Realm-Rolle für realmweite Berechtigungen oder eine Client-Rolle, die nur innerhalb dieses einen Clients gilt. Eine Gruppe wie "IT-Betrieb" bündelt diese Zuweisung für mehrere Personen gleichzeitig, sodass ein neues Teammitglied nur der passenden Gruppe beitreten muss, statt jede Rolle einzeln zu erhalten.
Next.js-Anwendung per OpenID Connect an Keycloak anbinden
Für eine Next.js-Anwendung übernimmt die Bibliothek Auth.js, der aktuelle Name des früher als next-auth bekannten Projekts, die technischen Details des OpenID-Connect-Protokolls. Auth.js bringt einen vorgefertigten Keycloak-Provider mit, der nur noch die Zugangsdaten aus dem eigenen Client-Eintrag braucht.
// auth.ts
import NextAuth from "next-auth"
import Keycloak from "next-auth/providers/keycloak"
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [Keycloak],
})
AUTH_KEYCLOAK_ID=grafana-intern
AUTH_KEYCLOAK_SECRET=<client-secret-aus-keycloak>
AUTH_KEYCLOAK_ISSUER=https://auth.beispiel-firma.de/realms/firma-intern
AUTH_SECRET=<zufaelliger-schluessel-fuer-auth-js>
Auth.js liest clientId, clientSecret und issuer automatisch aus diesen Umgebungsvariablen, sobald ihr Name mit AUTH_KEYCLOAK beginnt. Der issuer muss dabei genau den Realm-Pfad tragen, der auch in der Admin-Konsole steht, denn Auth.js hängt an diese Adresse selbst die Pfade für Login, Token-Austausch und Abmeldung an. Die Route für die Rückleitung nach dem Login lautet bei dieser Bibliothek standardmäßig /api/auth/callback/keycloak, und genau diese vollständige Adresse muss im Client-Eintrag unter "Valid redirect URIs" stehen, nicht nur die Domain der Anwendung.
Häufige Fehlerquellen
- Redirect-URI stimmt nicht exakt überein. Keycloak bricht den Login mit der Fehlermeldung "Invalid parameter: redirect_uri" ab, sobald die vom Client gesendete Adresse nicht zeichengenau mit einem Eintrag unter "Valid redirect URIs" übereinstimmt. Http statt https, ein fehlender oder zusätzlicher Schrägstrich am Ende oder ein falscher Port reichen für den Abbruch bereits aus; die vollständige Callback-Adresse der Anwendung gehört Zeichen für Zeichen in dieses Feld.
- Client authentication steht auf aus, die Anwendung erwartet aber ein Secret. Bleibt der Schalter "Client authentication" ausgeschaltet, richtet Keycloak den Client als public ein und erzeugt kein Client Secret. Trägt die Anwendungskonfiguration trotzdem ein
AUTH_KEYCLOAK_SECRETein, schlägt der Token-Austausch fehl, weil Keycloak für einen public Client gar kein Secret prüft. - Keycloak läuft im Produktivbetrieb weiter im Entwicklungsmodus. Der Befehl
start-devstartet Keycloak mit der eingebauten Datenbankdev-fileund ohne TLS-Erzwingung. Für den produktiven Einsatz verlangt Keycloak stattdessenstartbeziehungsweisestart --optimizedzusammen mit einer echten Datenbank wie PostgreSQL, sonst gehen alle Realms, Benutzer und Sessions beim nächsten Neustart des Containers verloren. - "Sign out all active sessions" gilt fälschlich als vollständige Sofort-Sperre. Diese Funktion beendet zwar alle aktiven Sitzungen und verhindert neue Zugriffstoken, widerruft laut Keycloak-Dokumentation aber keine bereits ausgestellten Zugriffstoken. Wer eine kompromittierte Anwendung wirklich sofort aussperren will, braucht zusätzlich eine kurze Gültigkeitsdauer für Zugriffstoken.
- Realm-Rolle und Client-Rolle werden verwechselt. Der Login gelingt, die Anwendung meldet aber trotzdem eine fehlende Berechtigung, weil eine Rolle nur für einen einzelnen Client vergeben wurde, während die Anwendung eine realmweite Rolle erwartet, oder umgekehrt. Vor der Fehlersuche im Anwendungscode lohnt sich deshalb zuerst der Blick in die Rollenzuweisung des betroffenen Benutzerkontos in der Admin-Konsole.
- Dasselbe Konto existiert in mehreren Realms parallel. Weil Realms vollständig voneinander isoliert sind, legt ein zweiter, versehentlich angelegter Realm ein zweites, unabhängiges Konto für dieselbe Person an. Deaktiviert ein Administrator daraufhin nur das Konto im ersten Realm, bleibt der Zugriff über den zweiten Realm bestehen, ohne dass das an irgendeiner Stelle auffällt.
Häufig gestellte Fragen
Was ist ein Realm in Keycloak?
Ein Realm ist in Keycloak ein eigenständiger, von anderen Realms vollständig isolierter Verwaltungsbereich für Benutzerkonten, Gruppen, Rollen und Clients. Innerhalb eines Realms teilen sich beliebig viele Anwendungen dieselben Benutzerkonten und denselben Login, während ein zweiter Realm auf demselben Keycloak-Server völlig unabhängig davon eigene Konten führt, etwa für einen anderen Mandanten oder eine externe Kundengruppe. Für ein Unternehmen mit ausschließlich internen Anwendungen genügt in aller Regel ein einziger Realm.
Was passiert mit bereits ausgestellten Zugriffstoken, wenn ein Benutzerkonto deaktiviert wird?
Ein bereits ausgestelltes Zugriffstoken bleibt nach der Deaktivierung eines Benutzerkontos zunächst gültig, bis es regulär abläuft. Keycloak stellt zwar keine neuen Zugriffstoken für dieses Konto mehr aus und lehnt jeden Versuch ab, über das Refresh-Token ein neues zu erhalten, prüft aber die Gültigkeit eines einmal ausgestellten, signierten Tokens nicht laufend nach. Wie schnell die Sperre in der Praxis wirkt, hängt deshalb direkt von der im Realm eingestellten Gültigkeitsdauer für Zugriffstoken ab; ein Wert von wenigen Minuten hält dieses Zeitfenster klein.
Warum zeigt Keycloak beim Einbinden einer neuen Anwendung den Fehler zu einer ungültigen Weiterleitungsadresse?
Keycloak zeigt die Fehlermeldung "Invalid parameter: redirect_uri", wenn die Adresse, an die eine Anwendung nach dem Login zurückgeleitet werden möchte, nicht zeichengenau mit einem der im Client hinterlegten Einträge unter "Valid redirect URIs" übereinstimmt. Der Vergleich unterscheidet zwischen http und https, prüft Port und Pfad und reagiert auch auf einen einzelnen zusätzlichen Schrägstrich am Ende der Adresse. Diese strenge Prüfung schützt vor sogenannten Open-Redirect-Angriffen, bei denen eine gefälschte Adresse ein gültiges Zugriffstoken an einen fremden Server statt an die echte Anwendung ausliefern würde.
Reicht Keycloak allein aus, oder braucht jede Anwendung trotzdem eine eigene Benutzerverwaltung?
Keycloak übernimmt Login, Passwort-Verwaltung und die Ausstellung von Zugriffstoken vollständig, sodass eine angebundene Anwendung selbst keine eigene Benutzertabelle mit Passwörtern mehr braucht. Was in der Anwendung bleibt, ist die Zuordnung eines eingeloggten Kontos zu anwendungsspezifischen Daten, etwa den eigenen Projekten oder Einstellungen einer Person, denn diese Informationen gehören fachlich zur Anwendung und nicht zur Identitätsverwaltung. Über die vom Zugriffstoken mitgelieferte eindeutige Benutzerkennung lässt sich diese Zuordnung ohne ein zweites Passwortfeld herstellen.