Keycloak im Plattformaufbau
Der Schlüssel zu sicherer und flexibler Benutzerverwaltung durch Backend-Fassaden
Sicheres Identity Management für moderne Anwendungen
Für moderne Anwendungen – vor allem im sicherheitskritischen Bereich – stehen Authentifizierung und Autorisierung von Nutzern sowie die Absicherung der Infrastruktur an erster Stelle. Wird perspektivisch der Aufbau einer Plattform erwägt, auf der mehrere Anwendungen aufsetzen, für die sich Benutzer oder Benutzerinnen bequem per Single Sign-on (SSO) anmelden können, bietet sich die Integration eines zentralen Identity Providers wie Keycloak (zur Webseite) an. Wo es Zugänge mit Rollen und Rechten gibt, müssen diese auch verwaltet werden – vorzugsweise in einem geschützten Bereich innerhalb der Anwendung.
Mit Hilfe von Keycloak lässt sich die Registrierung, Authentifizierung sowie Autorisierung von Nutzern schnell und einfach in die eigene Anwendung einfügen, aber dafür liegt die Benutzerverwaltung nun vollständig in der Hand von Keycloak. Einem Benutzer dafür Zugriff auf die Admin-Oberfläche von Keycloak zu gewähren ist aus Sicherheitsgründen ausgeschlossen, egal ob einfacher User oder Admin. Wie kann dennoch eine Benutzerverwaltung realisiert werden?
Die Lösung
Der Ansatz ist eine Fassade zwischen der Anwendung und Keycloak. Aus der Perspektive der Anwendung ist die Fassade lediglich ein Backend-Service mit einer API, worüber Benutzerdaten gelesen und geändert werden können. Diese Fassade nimmt Anfragen der Anwendung entgegen und stellt daraufhin eine oder mehrere Anfragen an die Keycloak Admin REST API, die eine programmatisch Verwaltung von Keycloak zulässt. Es ist zwar möglich, einem Nutzer anhand ausgelieferter Rollen Zugriff auf nur einzelne Funktionen der Admin API zu erlauben, aber die Option darüber gesendete Daten auf bestimmte und vor allem nicht sensible Felder zu limitieren, bietet Keycloak nicht an. Diese Funktion übernimmt die Fassade, indem diese Daten aus der Antwort von Keycloak auf ein für die Anforderungen relevantes Minimum reduziert und als eigene Antwort sendet.
Authentifizierung und Autorisierung sind nicht nur die Kommunikation zwischen Anwendung und Fassade relevant, sondern selbstverständlich auch für die zwischen Fassade und Keycloak. D.h. die Fassade muss sich ebenfalls gegenüber Keycloak authentifizieren und erhält zudem nur beschränkten Zugriff auf Admin API. Solch eine Fassade bildet die Grundlage für die Realisierung einer Benutzerverwaltung innerhalb der eigenen Anwendung, welche in der Lage ist Anforderungen der Anwendung und notwendige Sicherheit/Security miteinander zu vereinbaren.
Die Umsetzung mit Keycloak
Zunächst müssen in Keycloak die Voraussetzungen für einen Backend-Dienst, welcher für den Zugriff auf die Admin-API autorisiert ist, geschaffen werden. In Keycloak werden Entitäten wie Benutzer und Clients, aber auch Rollen und Gruppen in einem sog. Realm angelegt und verwaltet. Dabei stellen Clients einzelne Anwendungen oder Backend-Dienste dar, die einen Benutzer mit Keycloak authentifizieren. Für die Fassade wird im Realm, wo bereits der Client für die Anwendung existiert, ein neuer Client definiert. Dieser Client wird als sog. Confidential Client konfiguriert, was eine Authentifizierung über das Client Credentials Grant-Verfahren ermöglicht. Die dafür notwendigen Daten wie das Client Secret erhält die Fassade zu Beginn der Laufzeit auf einem gesicherten Weg. Hierfür kann auf Tools wie Kubernetes Secrets, HashiCorp Vault oder Azure Key Vault zurückgegriffen werden. Um die Fassade für den Zugriff auf Teile der Admin-API zu autorisieren, muss dem Service Account des neuen Client eine Reihe an Rollen zugewiesen werden, die im Client realm-management ausgeliefert werden.
Mit diesem Client stehen nun die Rahmenbedingungen für eine sichere Kommunikation zwischen Fassade und Keycloak. Um die Kommunikation zwischen Anwendung und Fassade abzusichern werden Rollen definiert, die für Benutzer mit Zugriff auf die Benutzerverwaltung vorgesehen sind. Anfragen von Benutzern, deren Authentifizierungs-Token keine dieser Rollen enthält, werden von der Fassade nicht akzeptiert. Daten wie Client ID, Name des Realm und notwendige Rollen werden der Fassade auf demselben gesicherten Weg wie das Client Secret geliefert.
Backend-Service / Fassade
Die Fassade wird mit der Programmiersprache Go aus dem Hause Google entwickelt. Go (auch bekannt als Golang) wird für ihre Einfachheit, starke Unterstützung von Nebenläufigkeit sowie seine Performance geschätzt und ist aus diesen Gründen ideal für die Implementierung von Services und Microservices geeignet. Die Architektur der Fassade umfasst zwei Komponenten. Den Kern bildet eine Client-Schicht, welche die Authentifizierung mit Keycloak sowie die Funktion einer Fassade vor Keycloak implementiert. Für den Client-Zugriff auf Keycloak verwenden wir die Bibliothek gocloak, mit Hilfe derer sich die Kommunikation mit Keycloak, sei es für Authentifizierung oder für API-Anfragen, leicht in die eigene Applikation integrieren lässt.
Die zweite Komponente ist eine äußere Gateway-Schicht, welche die API-Schnittstellen der Fassade zur Anwendung hin implementiert. Durch die strikte Trennung von der Client-Schicht lässt sich die Gateway-Schicht mit geringem Aufwand für beliebige Protokolle implementieren und integrieren, sei es REST/HTTP (openAPI), gRPC oder GraphQL. Dass mehrere verschiedene Gateway-Schichten nebeneinander existieren ist ebenfalls möglich.
Unser Fazit
Eine Anwendung oder Plattform mit sicherer Benutzerauthentifizierung und integrierter Benutzerverwaltung ohne Aufwand und in kürzester Zeit zu realisieren ist durchaus möglich. Mit Keycloak können Identity Management sowie SSO ohne Eigenimplementierung rasch aufgesetzt werden. Ein Backend-Dienst, welcher als Fassade zwischen Anwendung und Keycloak steht, bietet die Grundlage für eine Benutzerverwaltung nach eigenen Anforderungen – und das ohne die Sicherheit sensibler Benutzerdaten gefährden zu müssen. Vor allem die Flexibilität der Fassade hinsichtlich Kommunikationsprotokollen und Konfigurierbarkeit erleichtert deren Integration in bereits bestehende Infrastrukturen.