Verwaltung von Benutzerdaten in Microservice-Architekturen mit Keycloak und Spring Boot

Im Rahmen eines cloud-basierten Softwareprojekts stand ich kürzlich vor der Herausforderung eine Microservice-Applikation zu konzipieren, welche sowohl robuste Authentifizierungs- und Autorisierungsmechanismen als auch eine effiziente Verwaltung zusätzlicher Benutzerdaten erforderte.

In modernen Microservice-Architekturen ist die Absicherung von APIs und Diensten unerlässlich. OAuth 2.0 hat sich hier als De-facto-Standard etabliert, da es eine sichere und flexible Möglichkeit bietet, den Zugriff auf Ressourcen zu delegieren, ohne sensible Benutzerdaten wie Passwörter preiszugeben. Dies ist besonders wichtig in verteilten Systemen, in denen verschiedene Dienste miteinander kommunizieren müssen. OAuth 2.0 ermöglicht es, differenzierte Berechtigungen zu vergeben (Scopes), sodass beispielsweise eine Anwendung nur Zugriff auf bestimmte Benutzerdaten oder Funktionalitäten erhält. Dies minimiert das Risiko bei einer Kompromittierung eines einzelnen Dienstes.

Im Planungsprozess diskutierte unser Team die optimale Benutzerverwaltung und die Integration von OAuth 2.0. Dabei orientierten wir uns an etablierten Architekturprinzipien wie Clean Architecture, SOLID-Prinzipien und Separation of Concerns. Letztendlich entschieden wir uns, zusätzliche Nutzdaten der Benutzer – beispielsweise Präferenzen für Benachrichtigungen über neue Kurse – in einer separaten Datenbank zu verwalten, um eine klare Trennung der Verantwortlichkeiten und eine skalierbare Lösung zu gewährleisten.

Dieser Beitrag erläutert diese Entscheidung, beleuchtet die Vor- und Nachteile sowie die damit verbundenen Herausforderungen.

Einleitung

In modernen Microservice-Architekturen ist die Verwaltung von Benutzerdaten von zentraler Bedeutung. Keycloak ist eine leistungsstarke Open-Source-Identity- und Access-Management-Lösung, die sich nahtlos in Spring Boot und Spring Security integrieren lässt. Sie bietet umfassende Funktionen für Benutzerverwaltung, Authentifizierung und Autorisierung mittels OAuth 2.0. Während die Standardbenutzerverwaltung von Keycloak für viele Anwendungen ausreicht, bestand in unserem Projekt der Bedarf, zusätzliche benutzerspezifische Daten, wie etwa Benachrichtigungspräferenzen für Kurse, zu speichern.

Die zentrale Frage war: Sollen diese zusätzlichen Benutzerdaten in einer separaten Datenbank verwaltet oder direkt in Keycloak integriert werden? Nach sorgfältiger Abwägung verschiedener Lösungsansätze und unter Berücksichtigung architektonischer Prinzipien entschieden wir uns für eine separate Benutzerdatenbank, um eine klare Trennung der Verantwortlichkeiten und eine flexible Erweiterbarkeit zu erreichen.

Vorteile einer separaten Benutzerdatenbank

  1. Trennung von Verantwortlichkeiten: Durch die Verwendung von Keycloak für Authentifizierung und Autorisierung und einer separaten Datenbank für anwendungsspezifische Benutzerdaten wird eine klare Trennung der Verantwortlichkeiten erreicht. Dies entspricht dem Prinzip der Separation of Concerns und fördert die Wartbarkeit und Skalierbarkeit der Anwendung.
  2. Flexibilität und Erweiterbarkeit: Eine separate Datenbank ermöglicht die Speicherung spezifischer Benutzerinformationen, die möglicherweise nicht direkt von Keycloak unterstützt werden. Beispielsweise speichert Keycloak standardmäßig keine detaillierten Benachrichtigungspräferenzen für Kurse. Dadurch bleibt die Keycloak-Konfiguration übersichtlich und konzentriert sich auf ihre Kernfunktionen. Dies unterstützt das Open/Closed-Prinzip der SOLID-Prinzipien, indem bestehende Systeme offen für Erweiterungen bleiben, ohne modifiziert werden zu müssen.
  3. Unabhängigkeit von der Identitätsplattform: Die Anwendung ist weniger stark von der spezifischen Implementierung von Keycloak abhängig. Ein späterer Wechsel zu einem anderen Identity Provider gestaltet sich einfacher, da die zusätzlichen Benutzerdaten getrennt verwaltet werden. Dies fördert die Modularität und Flexibilität der Architektur.

Nachteile und Herausforderungen

  1. Datenkonsistenz: Die Verwaltung von Benutzerdaten in zwei separaten Systemen kann zu Inkonsistenzen führen. Änderungen in Keycloak müssen in der separaten Datenbank synchronisiert werden, was geeignete Synchronisationsmechanismen erfordert. In Betracht kommen beispielsweise Event Sourcing, Change Data Capture (z.B. mit Debezium) oder regelmäßige Batch-Jobs. Event Sourcing bietet den Vorteil einer vollständigen Historie der Änderungen, erhöht aber die Komplexität. Debezium ermöglicht eine effiziente Erfassung von Änderungen an der Datenbank, während Batch-Jobs einfacher zu implementieren sind, aber potenziell zu Verzögerungen führen können.
  2. Sicherheit: Zusätzliche Benutzerdaten erhöhen den Sicherheitsaufwand. Es müssen geeignete Maßnahmen getroffen werden, um sensible Informationen zu schützen und den Zugriff zu kontrollieren.
  3. Erhöhte Komplexität: Das Hinzufügen einer weiteren Datenbank erhöht die Komplexität der Architektur. Es fallen zusätzliche Komponenten an, die verwaltet, migriert und gesichert werden müssen.
  4. Performance: Abfragen, die Daten sowohl aus Keycloak als auch aus der separaten Datenbank benötigen, können die Performance beeinträchtigen. Eine effiziente Gestaltung der Microservices ist erforderlich, um eine optimale Performance zu gewährleisten.

Alternativen

  1. Keycloak Benutzerattribute: Keycloak bietet die Möglichkeit, benutzerdefinierte Attribute zu speichern. Für einfache zusätzliche Daten, wie z.B. eine einzelne Präferenz, könnten diese direkt in Keycloak verwaltet werden. Für komplexere Datenstrukturen oder eine große Anzahl von Attributen ist diese Option jedoch weniger geeignet.
  2. User Federation: Falls zusätzliche Benutzerdaten bereits in einem anderen Verzeichnis vorhanden sind (z.B. LDAP), kann Keycloak’s User Federation verwendet werden, um diese Daten zu integrieren, ohne eine separate Datenbank zu benötigen. Dies ist sinnvoll, wenn bereits eine etablierte Benutzerdatenquelle existiert und eine Konsolidierung gewünscht ist.
  3. Dedizierter Microservice für Benutzerdaten: Eine weitere Möglichkeit ist die Implementierung eines dedizierten Microservices, der ausschließlich für die Verwaltung zusätzlicher Benutzerdaten zuständig ist. Dieser Service kann unabhängig von Keycloak skaliert und verwaltet werden. Im Vergleich zur direkten Verwendung einer Datenbank bietet diese Variante eine stärkere Kapselung und ermöglicht komplexere Geschäftslogik in Bezug auf die Benutzerdaten. Die Entscheidung für eine separate Datenbank statt eines dedizierten Microservices wurde in diesem Fall aufgrund der geringeren Komplexität und des geringeren Entwicklungsaufwands getroffen.

Architekturbeispiel mit PlantUML-Sequenzdiagramm

Die Analyse der Anforderungen führte zur Konzeption einer Architektur, in der Keycloak die zentrale Rolle in der Authentifizierung und Autorisierung übernimmt, während zusätzliche Benutzerdaten in einer separaten Datenbank verwaltet werden. Dies folgt den Prinzipien der Clean Architecture und trennt die Geschäftslogik von der Infrastruktur.

Im nachstehend dargestellten Beispiel bucht ein Kunde einen Kurs über das Frontend. Das API Gateway validiert den Authentifizierungstoken des Kunden bei Keycloak. Bei erfolgreicher Validierung wird die Buchungsanfrage an den Course Service weitergeleitet, welcher die Buchung in der Kursdatenbank speichert und optional Benutzerdaten vom User Service abruft.

Beispiel: Kursbuchung durch einen Kunden

Das obige Sequenzdiagramm veranschaulicht den Ablauf einer Kursbuchung und die Interaktion der verschiedenen Dienste. Dabei wird deutlich, dass die Verwaltung zusätzlicher Benutzerdaten, insbesondere im Kontext der Authentifizierung mit Keycloak, einige Herausforderungen mit sich bringt. Um diese Herausforderungen zu meistern und eine robuste, sichere und skalierbare Lösung zu gewährleisten, sollten die folgenden Best Practices beachtet werden.

Best Practices

  • API-gesteuerte Kommunikation: Verwenden Sie gut definierte APIs für die Kommunikation zwischen den Microservices und der Datenbank. Dies fördert die lose Kopplung und erleichtert die Wartung.
  • Automatisierte Synchronisation: Implementieren Sie Mechanismen wie Event Sourcing oder Change Data Capture, um Änderungen in Keycloak automatisch in der Benutzerdatenbank zu spiegeln.
  • Sicherheitsüberprüfungen: Führen Sie regelmäßige Sicherheitsüberprüfungen durch, um sicherzustellen, dass sowohl Keycloak als auch die separate Benutzerdatenbank den aktuellen Sicherheitsstandards entsprechen.
  • Skalierbarkeit: Stellen Sie sicher, dass sowohl Keycloak als auch die separaten Datenbanken skalierbar sind, um den wachsenden Anforderungen der Anwendung gerecht zu werden.

Fazit

Die Implementierung dieser Architektur im skizzierten Projekt demonstrierte die Effektivität und Zukunftsfähigkeit der Kombination von Keycloak mit einer separaten Benutzerdatenbank. Die vorgelagerte Analyse der Anforderungen und die Diskussion verschiedener Lösungsansätze, insbesondere im Hinblick auf die Integration von OAuth 2.0, resultierte in einer Architektur, die Sicherheit, Flexibilität und gute Wartbarkeit vereint. Die Entscheidung für eine separate Datenbank ermöglichte die Abbildung spezifischer Anforderungen, wie z.B. detaillierte Benachrichtigungspräferenzen, ohne die Kernfunktionalität von Keycloak zu beeinträchtigen. Gleichzeitig wurden die mit dieser Entscheidung verbundenen Herausforderungen, wie die Notwendigkeit der Datensynchronisation, durch die Auswahl geeigneter Mechanismen adressiert. Insgesamt bietet diese Architektur eine robuste und skalierbare Lösung für die Verwaltung zusätzlicher Benutzerdaten in modernen Microservice-Umgebungen.

💡
Möchten Sie tiefer in die Entwicklung von Microservices mit Spring Boot eintauchen? Dann laden ich Sie herzlich ein, an meinen Microservice mit Spring Boot Kurs bei letsboot.ch teilzunehmen.
In diesem umfassenden Kurs führe ich Sie Schritt für Schritt durch die wichtigsten Konzepte und Best Practices, um moderne, skalierbare und wartbare Anwendungen zu entwickeln. Nutzen Sie die Gelegenheit, Ihr Wissen zu erweitern und praktische Fähigkeiten zu erwerben, die Sie in Ihren eigenen Projekten anwenden können.