zurück zum Artikel

Eine Identität für alles mit Keycloak

David Klassen
Eine Identität für alles mit Keycloak

Keycloak ist eine Open-Source-Software, die Red Hat als Implementierung von OpenID Connect veröffentlicht hat. Entwickler können sie einfach und flexibel zur Authentisierung für eigene Applikationen verwenden.

Die Anforderungen an Internetdienste haben sich in den letzten Jahren stark verändert. Die Zeiten, in denen Nutzer sich für jeden Dienst neu registrierten, sind längst vorbei. Stattdessen möchten man heute seine Identität einmalig bei Anbietern wie Google oder Facebook verwalten und neuen Diensten lediglich Zugriff auf diese Identität gewähren. Die praktische Umsetzung des Zugriffs erfolgt durch den Klick auf einen Google- oder Facebook-Log-in-Button innerhalb des Dienstes. Dieses Vorgehen hat einige Vorteile: Unter anderem vereinfacht das Zentralisieren des kompletten Authentifizierungsprozesses auf einen einzigen Identity Provider das Single-Sign-On. Allerdings potenziert sich der Schaden, falls ein Benutzerkonto erfolgreich in den Händen von Angreifern landet.

Dank des 2014 veröffentlichten OpenID-Connect-Protokolls und Keycloak von Red Hat als zertifizierte Implementierung des Protokolls lässt sich das Anmeldeverfahren verhältnismäßig einfach und schnell in eigenen Systemlandschaften umsetzen. Die Macher von Keycloak haben sich mit ihrer Software zum Ziel gesetzt, das Thema Security für Entwickler von Applikationen und Services deutlich zu vereinfachen. Dabei übernimmt die Software nicht nur die reine Autorisierung, sondern kümmert sich zusätzlich auch um die Authentisierung der Benutzer. Administratoren müssen diese bei der Installation von Keycloak in eine bestehende Infrastruktur nicht neu anlegen, sondern können sie einfach aus gegebenenfalls bestehenden LDAP- beziehungsweise Active-Directory-Servern verwenden.

Keycloak ist im Wesentlichen ein vorkonfigurierter Wildfly Application Server, der separat von den abzusichernden Anwendungen läuft. Abbildung 1 zeigt, wie die Anwendungen beziehungsweise der Client die Benutzer zur Anmeldung an Keycloak weiterleitet, das die Credentials entgegennimmt und weiterverarbeitet. Das Vorgehen isoliert die Anwendung von den zu schützenden Anmeldeinformationen der Benutzer. Das reduziert nicht nur potenzielle Sicherheitslücken bei der Verarbeitung und Weiterleitung sensibler Credentials, sondern bietet zudem die Möglichkeit, eigene Benutzer in fremden Applikationen über eine zentrale Keycloak-Instanz zu authentifizieren. Der Vorteil dabei ist, dass man diese fremden Applikationen anbinden kann, ohne damit die eigentlichen Credentials beziehungsweise Informationen der eigenen Benutzer preisgeben zu müssen.

Der Client reicht die Nutzerdaten zur Authentifizierung an Keycloak weiter. Die Anwendung erhält nach erfolgreicher Authentifizierung das Access- & ID-Token (Abb. 1).

Der Client reicht die Nutzerdaten zur Authentifizierung an Keycloak weiter. Die Anwendung erhält nach erfolgreicher Authentifizierung das Access- & ID-Token (Abb. 1).

Hinsichtlich der Art der Authentifizierung ist Keycloak sehr flexibel. Unter anderem lassen sich Benutzer innerhalb von Keycloak gegen ein Active Directory oder einen LDAP-Server authentifizieren. Optional lässt sich Keycloak als Kerberos Bridge einsetzen, um Benutzer, die sich beispielsweise durch das Windows-Log-in bereits an einem Kerberos-Server angemeldet haben, automatisch zu authentifizieren. Ebenso ist der Einsatz von Keycloak als Identity Broker möglich, der die Authentifizierung an einen externen Identity Provider beziehungsweise an ein soziales Netz wie Facebook, Google oder GitHub delegiert. Im einfachsten Fall verwenden Administratoren die mitgelieferte Datenbank und legen die Benutzer über eine Administrationsoberfläche neu an oder überlassen ihnen die Registrierung.

Nach der erfolgreichen Authentifizierung eines Benutzers stellt Keycloak neben einem Access Token ein Identity Token in Form eines JSON Web Token (JWT) für den Benutzer an die jeweilige Anwendung aus (vgl. Schritt 4 in Abb. 1). Das Access-Token befähigt die Anwendung dazu, im Namen des Benutzers Dienste aufzurufen. Das Identity Token enthält dagegen vor allem Informationen über die Identität des Benutzers. Es stellt den wesentlichen Unterschied zwischen OAuth 2.0 und dessen Erweiterung OpenID Connect dar: Anders als im klassischen OAuth-2.0-Protokoll berücksichtigt es nicht nur die Rechte in Form von Access-Tokens, sondern zusätzlich die Identität der Nutzer. Über das Identity Token können Anwendungen direkt Informationen wie den kompletten Namen oder die E-Mail der Nutzer auslesen. Bei Bedarf lassen sich dem Identity Token über Keycloak zusätzlich eigene Attribute hinzufügen.

Da mehrere Anwendungen (Clients) an eine Keycloak-Instanz angeschlossen sind, sind die Benutzer nach der Anmeldung automatisch an allen verbundenen Clients angemeldet und müssen sich somit nicht mehr für jede weitere Applikation einzeln anmelden. Aus Anwendersicht verbessert sich somit die Usability der Anwendungen. Für Betreiber vereinfacht das Verfahren die Benutzerverwaltung deutlich, da sie deren Rechte und Rollen nicht mehrfach pflegen und verwalten müssen.

Red Hat hat sich mit Keycloak zum Ziel gesetzt, den Einsatz für Entwickler im Enterprise-Umfeld so einfach wie möglich zu gestalten. Daher ist mit Keycloak nicht nur ein vollständiger Identity Provider als Open-Source-Software verfügbar, sondern auch unterschiedliche Adapter für die direkte Anbindung von Anwendungen in JavaScript oder Java unter anderem zum Verwenden mit JSF, Spring Boot und Applikationsservern wie JBoss/Wildfly und Tomcat. Damit können Entwickler Keycloak im simpelsten Fall rein konfigurativ implementieren, indem sie den passenden Adapter auf dem für die Applikation verwendeten Anwendungsserver installieren und eine Verbindung mit der Keycloak-Instanz über entsprechende Konfigurationen herstellen. Der weitere Artikel zeigt den groben Ablauf der Installation und die Anbindung von Keycloak an eine existierende Spring-Boot-Applikation.

Zur Installation von Keycloak laden Entwickler die Standalone-Server-Distribution von der offiziellen Homepage [1] herunter. Nach dem Entpacken erhalten sie einen vollständig konfigurierten Wildfly Application Server, den sie über das Skript ...\bin\standalone.bat beziehungsweise .../bin/standalone.sh starten. Anschließend erreichen sie über die URL http://localhost:8080/auth die Startseite von Keycloak, um dort zunächst ein Admin-Konto zu erstellen und dafür Benutzername und Passwort zu vergeben. Im Anschluss daran loggen sie sich mit den Credentials in die Admin-Oberfläche unter http://localhost:8080/auth/admin ein (vgl. Abb. 2).

Admin-Oberfläche von Keycloak (Abb. 2)

Admin-Oberfläche von Keycloak (Abb. 2)

(Bild: Keycloak)

An dieser Stelle können Entwickler bereits damit beginnen, Keycloak über die Admin-Oberfläche für die abzusichernde Spring-Boot-Applikation zu konfigurieren. Dazu erstellen sie im ersten Schritt einen sogenannten Realm (Reich). Realms sind in sich geschlossene Mengen von Benutzern, Credentials, Rollen und Gruppen. Sie erlauben es, mehrere Benutzerbereiche völlig isoliert voneinander innerhalb einer Keycloak-Instanz zu verwalten.

Anschließend folgt das Anlegen eines neuen Clients. Dafür ist zunächst die Definition einer Redirect-URL notwendig – für die restlichen Einstellungen lassen sich zunächst die Standardwerte übernehmen. Keycloak leitet die Benutzer nach erfolgreicher Authentifizierung an die Redirect-URL weiter. Die für den Client einzutragende URL ist im konkreten Fall die der Spring-Boot-Applikation. Damit sind alle Schritte erledigt, die auf Keycloak-Seite zur Konfiguration eines neuen Clients nötig sind.

Die folgenden Absätze widmen sich der Anpassung der Spring-Boot-Applikation und gehen davon aus, dass die abzusichernde Spring-Applikation bisher durch kein Framework abgesichert ist. Wer die Anwendung beispielsweise bereits mit Spring Security geschützt hat, kann einen Spring-Security-Adapter verwenden. Das Beispiel zeigt jedoch den Einsatz des Spring-Boot-Adapters. Dazu ist zunächst die entsprechende Abhängigkeit notwendig – folgender Codeauszug setzt auf Gradle als Build-Werkzeug. Durch das Hinzufügen der Dependency erkennt Spring Boot beim Starten der Anwendung, dass es Keycloak verwenden soll, und setzt automatisch die benötigten Konfigurationen:

dependencies {
(...)
compile('org.keycloak:keycloak-spring-boot-starter')
(...)
}

Im zweiten Schritt müssen Entwickler den hinzugefügten Adapter in application.properties konfigurieren. Dazu geben sie die URL zur Startseite von Keycloak, den Namen des neu angelegten Realm und den Namen des darin angelegten Clients an. Weiterhin setzen sie den Wert keycloak.public-client auf true. Diese Einstellung gilt für Webseiten beziehungsweise Clients, die nicht in der Lage sind, ein Secret sicher zu verwahren – beispielsweise reine JavaScript-Webseiten. Für diese greifen andere Mechanismen, um den Client dennoch erfolgreich in Keycloak zu authentifizieren. Weitere Details beziehungsweise Konfigurationen lassen sich der offiziellen Dokumentation [2] entnehmen.

Die beiden letzten Zeilen spezifizieren die für Java EE typischen Security Constraints. Das folgende Listing legt somit fest, dass nur Benutzer mit der Rolle user auf die Seiten gelangen, deren URL auf das Pattern /products/* passt:

keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=TestRealm
keycloak.public-client=true
keycloak.resource=TestClient
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=
/products/*

Nach den beiden Schritten ist die Anwendung erfolgreich als Client an Keycloak gebunden. Sobald Benutzer nun innerhalb der Spring-Boot-Applikation eine URL aufrufen, die auf das beschriebene Pattern passt, verweist die Anwendung sie an die angebundene Keycloak-Instanz, um sich dort anzumelden. Erst anschließend erfolgt die Weiterleitung an die gewünschte Seite. Zum Testen müssen Entwickler nur noch einen Benutzer mit der Rolle user in Keycloak anlegen. Analog können sie weitere Rollen oder Security Constraints setzen.

Wer innerhalb der Spring-Boot-Anwendung auf die Identität des angemeldeten Benutzers eingehen möchte, kann das ID-Token aus dem Request ziehen und damit alle übergebenen Informationen bequem laden. Beispielsweise lässt sich der Benutzernamen auslesen und innerhalb der Anwendung an passender Stelle platzieren, wie folgendes Listing zeigt:

KeycloakSecurityContext securityContext = 
((KeycloakPrincipal) request.getUserPrincipal())
.getKeycloakSecurityContext();

IDToken idToken = securityContext.getIdToken();
String userName = idToken.getName();

AccessToken accessToken = securityContext.getToken();
Set<String> userRoles =
accessToken.getRealmAccess().getRoles();

Ebenso bequem können Entwickler das Access-Token und die darin enthaltenen Benutzerrollen aus dem Request laden. Mit den Rollen können sie innerhalb einer Seite beispielsweise bestimmte Buttons oder Labels nur für Benutzer mit der Rolle admin sichtbar schalten.

Die Administration von Keycloak erfolgt über ein Webfrontend, dessen Oberfläche alle benötigten Einstellungen übersichtlich anzeigt. Optional lassen sich das Admin CLI oder eine REST API zur Administration verwenden. Wer Keycloak aus einer Java-Anwendung heraus administrieren oder manuelle Aufgaben programmatisch vereinfachen möchte, kann eine bestehende Java-Client-Bibliothek nutzen, die im Hintergrund die REST API aufruft. Das System bietet somit weitreichende Mechanismen zur Automatisierung der Administration.

OpenID Connect und damit auch Keycloak basieren weitgehend auf JSON Web Token (JWT). Der offene Standard zum Erstellen von Access-Tokens soll vor allem die Integrität von Anfragen sicherstellen. Dazu wird das Token in drei Elemente geteilt, die durch einen Punkt voneinander getrennt sind. Die folgende Abbildung zeigt auf der linken Seite das Token und rechts die dekodierte Version.

Beispiel für ein JSON Web Token (Abb. 3)

Beispiel für ein JSON Web Token (Abb. 3)

(Bild: JWT.io)

Der eigentliche Inhalt des JWT (Payload) steckt im mittleren Teil, der die Beschreibung der sogenannten Claims als Key/Value-Paare enthält. Im OpenID-Connect-Kontext sind an der Stelle beispielsweise der Name oder die E-Mail des Benutzers aufgeführt. Im ersten Teil des JWT finden sich der Header und damit der Algorithmus zum Signieren und/oder Verschlüsseln des Tokens sowie der Tokentyp, der bei JWT stets jwt ist. Das Ergebnis des Signierens steht im letzten der drei Teile, der Signatur. Sie wird aus dem Header, dem Payload und einem Secret berechnet, das nur der Server kennt. Die Vorgehensweise stellt sicher, dass die enthaltenen Claims valide sind und niemand die Payload eines JWT verändert beziehungsweise manipuliert hat.

Der Server, der die JWTs entgegennimmt, prüft nur noch die Validität des Tokens und gewährt den Benutzern im Erfolgsfall Zugriff auf die angeforderten Ressourcen. Somit müssen die Betreiber der Anwendung nicht mehr unterschiedliche Sessions für die individuellen Benutzer auf dem Server halten und können die Infrastruktur völlig stateless betreiben. Damit sparen sie serverseitig Speicher und reduzieren die Anzahl der Datenbankzugriffe. Der Preis dafür ist eine höhere Anforderung an die Rechenleistung, da das System die JWTs jeweils einzeln validieren muss. Wer mehr über JWT lernen möchte und wissen will, warum sie sich besonders gut für Microservice-Architekturen eigeen, findet in einem Talk von Hubert Sablonnière nützliche Informationen:

Talk von Hubert Sablonnière zum Einsatz von JWT

Die genauere Betrachtung und Analyse von Keycloak zeigt, dass es Entwicklern alles bietet, was sie für die Autorisierung und Authentisierung benötigen. Die Software zeichnet sich vor allem durch Schlichtheit aus, kann aber ebenso gut kompliziertere Anwendungsfälle abbilden. Da es sich um eine zertifizierte Implementierung des OpenID-Connect-Protokolls handelt, die quelloffen zur Verfügung steht, ist die Software eine attraktive Alternative gegenüber proprietären Eigenentwicklungen. Die ausführliche Dokumentation erleichtert die Einarbeitung in Keycloak, und erste Ergebnisse lassen nicht lange auf sich warten. Daher spricht vieles dafür, Keycloak in passenden Kundenprojekten zu verwenden. Interessierte Programmierer können sich zudem an der Entwicklung von Keycloak mit Contributions am GitHub-Repo https://github.com/keycloak/keycloak beteiligen.

David Klassen
hat Informatik studiert und ist aktuell Software Engineer bei der adesso AG. Dort beschäftigt er sich neben Kundenprojekten mit der Nutzung und Weiterentwicklung von Open-Source-Software.

(rme [3])


URL dieses Artikels:
https://www.heise.de/-3834525

Links in diesem Artikel:
[1] http://www.keycloak.org/downloads.html
[2] https://keycloak.gitbooks.io/documentation/securing_apps/topics/oidc/java/spring-boot-adapter.html
[3] mailto:rme@ix.de