Skalierbare Authentifizierung – Föderation statt Integration

Photo of author
Sven-Torben Janus

Wie sinnvoll ist eine tiefe Integration von Authentifizierungslösungen im Zeitalter von verteilten, dezentralen Systemen und Microservices noch?
Gar nicht – zumindest nicht unter der Prämisse, dass die Entscheidung zum Einsatz verteilter (Microservice-) Architekturen oftmals auf Argumenten der Skalierung beruht.

Als IT-Berater sind wir immer wieder mit Integrationsprojekten befasst. Vor allem im Rahmen von Modernisierungs- oder Neuimplementierungsprojekten kommt man dabei irgendwann immer an den Punkt eine Authentifizierungslösung zu integrieren. Oftmals ist in solchen Projekten eine der Randbedingungen, die vorhandene Identitätsmanagementlösung (IAM) zu nutzen.

Aber wie sinnvoll ist eine tiefe Integration solcher Lösungen im Zeitalter von verteilten, dezentralen Systemen und Microservices noch?

Gar nicht – zumindest nicht unter der Prämisse, dass die Entscheidung zum Einsatz verteilter (Microservice-) Architekturen oftmals auf Argumenten der Skalierung beruht.

Das Problem mit der Integration

Um das Problem zu verstehen, betrachten wir zunächst einmal den Fall einer monolithischen Architektur. Das hier traditionell vorherrschende Paradigma zur Identitätskontrolle sieht in der Regel folgendermaßen aus.

Alle Benutzerinformationen sind in einem zentralen Repository (z.B. LDAP, Active Directory, Datenbank etc.) gespeichert. Durch eine direkte Integration einer Sicherheitskomponente in der Anwendung, die wie eine Barriere funktioniert, wird sichergestellt, dass der Benutzer authentifiziert wird. Da alle Komponenten in einem Monolithen gemeinsam deployed sind, teilen sie sich dadurch die Verbindung zum Repository, aber auch den Zustand der Authentifizierung. Alle Komponenten wissen, ob und welcher Benutzer angemeldet ist.

Die Sicherheitskomponente prüft die Anmeldedaten des Benutzers gegen das Repository. Sind die Anmeldedaten korrekt, wird die Identität des Benutzers an die anderen Komponenten weitergereicht und von diesen nicht weiter geprüft. Oftmals geht dies einher mit der Etablierung einer Session zwischen Client und Server. Hierbei handelt es sich um eine Optimierung. Sie dient dazu, dass nicht bei jeder Anfrage an den Server die Identität des Benutzers ermittelt und erneut sichergestellt werden muss. Diese ist stattdessen mit der etablierten Session verheiratet.

Übertragen wir diese Art der Integration in eine verteilte Microservice-Architektur, ergibt sich vor dem Hintergrund der Skalierbarkeit vor allem ein Problem. Jede einzelne Komponente ist nun quasi in einem eigenständigen Microservice deployed. Das hat zur Folge, dass auch jeder Microservice seine eigene Sicherheitskomponente bzw. Barriere benötigt. Jeder Service hat somit auch eine Verbindung an das Repository und muss bei einer Anfrage die Anmeldedaten des Benutzers prüfen.

Das ist nicht nur in Hinblick auf die Systemabhängigkeiten ein Albtraum. Jeder Microservice hat jetzt nicht nur eine Abhängigkeit auf das zentrale Repository; sollten sich einzelne Microservices untereinander aufrufen, ist dieses Vorgehen zusätzlich hochgradig ineffizient. Eine solche Aufrufkette endet zwangsweise in mehreren Anfragen an das Repository. Außerdem kann die Nutzung von Sessions nur sinnvoll aufrechterhalten werden, wenn sich alle Microservices die Sessioninformationen teilen. Eine weitere Kopplung zwischen allen Microservices.

OAuth2 als Basis für eine Lösung

Eine weitaus effizientere Lösung bieten Mechanismen wie OAuth2. OAuth2 unterscheidet im Wesentlichen vier Parteien, die miteinander kommunizieren. Zum einen ist dies ein s.g. Resource Owner. Das ist der Benutzer, der unsere Microservices nutzen möchte. Dieser bedient sich eines Clients. Das kann z.B. eine mobile App oder ein Single Page Application sein. Die eigentliche Authentifizierung erfolgt durch einen Authorization Server. Letztlich werden die Microservices als Resource Server bezeichnet.

Der Ablauf, um einem Benutzer Zugriff auf einen Microservice zu gewähren, ist etwas komplex, stellt sich aber in etwa wie folgt dar:
Der Benutzer fragt über seinen Client den Zugriff auf den Resource Server beim Authorization Server an. Der Authorization Server authentifiziert den Benutzer anhand seiner Anmeldedaten wie z.B. Benutzername und Passwort. Sind diese korrekt, stellt der Authorization Server ein s.g. Access Token an den Client aus. Dieser kann das Access Token nutzen, um den Ressource Server aufzurufen.

Dabei sendet der Client bei jedem Aufruf des Ressource Servers das Access Token mit. Der Ressource Server kann den Zugriff auf die angefragten Daten oder Funktionalitäten freigeben, nachdem er das Access Token validiert und dessen Gültigkeit festgestellt hat.

Dazu hat der Resource Server zwei Möglichkeiten:

Zum einen kann er mit dem Token den Authorization Server anfragen, der für ihn das Access Token verifiziert. Der Authorization Server kann dann mit relevanten Informationen antworten, wie z.B. dem Benutzernamen, dem Ablaufzeitpunkt des Tokens und mehr oder minder beliebigen weiteren Informationen.
Problematisch ist hierbei in unserem Szenario jedoch, dass wieder eine Integration der Resource Server (unserer Microservices) mit einem zentralen System (dem Authorization Server) notwendig wird. In diesem Falle hätten wir nur das Benutzer-Repository gegen den Authorization Server ausgetauscht. Im Sinne der Skalierbarkeit hätten wir somit nichts gewonnen.

Föderative Authentifizierung

Allerdings besteht für den Resource Server auch noch eine andere Möglichkeit das Token zu verifizieren, die diese Integration nicht notwendig macht. Die Lösung liegt hier in der Kryptographie oder genauer in einem Public-Key-Verschlüsselungsverfahren oder zumindest einer entsprechenden Signatur.

Der Authorization Server kann die vom Resource Server benötigten Informationen einfach in das Access Token codieren. Das Token kann er dann mit einem privaten Schlüssel verschlüsseln oder zumindest signieren. Der Resource Server verfügt über den entsprechenden öffentlichen Schlüssel und kann somit die Echtheit des Tokens prüfen. Diese Art der Integration macht keine direkte Kommunikation zwischen Resource Sever und Authorization Server notwendig.

Man spricht daher hier auch von einem föderativen Authentifizierungsverfahren. Das Verfahren basiert ausschließlich auf Vertrauen. Offensichtlich wird auf Basis des Public-Key-Verschlüsselungsverfahrens eine Vertrauensstellung zwischen Authorization Server, Ressource Server und Client etabliert.

Als Standard hat sich hierzu mit OpenId Connect eine Erweiterung des OAuth2-Protokolls etabliert. Während Access Tokens im Rahmen von OAuth2 oftmals von Clients nicht interpretierbar sind (z.B. zufällig generierte GUIDs), standardisiert OpenId Connect wie Identitätsinformationen in das Token codiert werden können. Hierzu setzt es auf einen weiteren Standard auf, nämlich JSON Web Tokens (JWTs). Diese erlauben es mittels JSON Objekten s.g. Claims zwischen Parteien auszutauschen. Es ist somit möglich weitere Informationen wie Gruppenzugehörigkeit, Rollen oder ähnliches in die Tokens zu codieren.

Zentrale Integration

Wie hilft uns das bei unserem ursprünglichen Problem – der Integration einer vorhandenen Authentifizierungslösung?

Indem wir die Integration auf einen einzelnen Punkt in der Gesamtsystemumgebung beschränken können. Das vorhandene System muss nun ausschließlich mit dem Authorization Server integriert werden. In einem föderativen Ansatz authentifiziert nur dieser den Benutzer.

Unsere Microservices müssen lediglich die Access Tokens verifizieren. Sie erhalten alle notwendigen Informationen (insbesondere die Identität des Benutzers) durch deren Übermittlung bei jeder Anfrage direkt mitgeliefert. Müssen einzelne Microservices andere Microservices aufrufen, können Access Tokens außerdem für eine Delegation genutzt werden.

Förderation statt Integration

Wie wir gesehen haben, bieten föderative Authentifizierungsmechanismen große Vorteile in Bezug auf die Skalierbarkeit verteilter Systemarchitekturen wie Microservices.

Die Kopplung aller Teilsysteme an ein zentrales Repository wird massiv verringert, so dass sich wesentlich weniger (direkte) Abhängigkeiten zwischen den Systemen ergeben. Auch die Kopplung von Microservices durch Aufrufe untereinander kann so effizienter gestaltet werden. Die Notwendigkeit der Verifizierung der Benutzeridentität gegen ein zentrales System entfällt.

Ich empfehle daher dringen zu prüfen, ob ein föderativer Ansatz bei der Anbindung vorhandener IAM-Lösungen eine Option darstellt. Gerne unterstützen unsere Architekturberater in dieser und ähnlichen Fragestellungen.

2 Gedanken zu „Skalierbare Authentifizierung – Föderation statt Integration“

  1. Schöne Darstellung der Motivation und Umsetzung einer föderalen Autorisierung. Bei der Sicherheitsbewertung solcher Lösungen stellen wir uns allerdings immer eine Frage: Wie handhabt man am besten die Rolle des Authorization Servers? Wir sehen zunehmend Websites, die sich auf große Authorization-Service-Provider wie Google oder Facebook verlassen („Loggen Sie sich mit Ihrem G+/Facebook-Account ein!“).

    Das hat zunächst einmal eine Reihe von Vorteilen: Es ist einfach integriert, da kein eigener Authorization Server betrieben werden muss. Auch für Benutzer ist das mit einigem Komfort verbunden: Passwort-Manager einmal außen vor gelassen, haben viele Anwender Schwieirigkeiten für jeden Webdienst ein eigenes (sicheres!) Passwort zu merken. Für Google oder Facebook mag das noch gerade klappen.

    Doch damit ist es auch nicht weit zum ersten Unbehagen: Wenn ich mich im neuen Online-Weinhandel https://wilde-weine-der-toskana.de/ anmelden möchte, wieso fragt mich dann Mark Zuckerberg nach meinem Passwort? Stecken die beiden auch schon unter einer Decke? Welche Informationen erfährt Facebook über meinen Weinkonsum, welche Kaufgewohnheiten leiten die US-Amerikaner an den Delikatessenladen weiter? Für Anwender ist das nicht einfach ersichtlich.

    Der Beitrag hat ja bereits darauf hingewiesen: Es geht hier um Vertrauen. Anbieter von OAuth-Diensten haben letztlich Zugriff auf die Angebote, die ihn zur Authentisierung und Autorisierung nutzen. Was empfehlen Sie daher: Eigene Infrastruktur aufbauen und betreiben (teurer und aufwändiger, aber mit mehr Kontrolle) oder auf bestehende Systeme zurückgreifen (bessere User Experience, aber Abgabe der Kontrolle)?

    Antworten
    • Hallo Herr Magnus,

      zunächst einmal herzlichen Dank für das Feedback zu meinem Blogbeitrag.

      Zu ihrer Frage kann ich jedoch lediglich die übliche Beraterantwort geben – „it depends“. Je nach Art und Umfang des Projektes kann man zu sehr unterschiedlichen Einschätzungen gelangen.
      Wie Sie bereits selbst erläutern, sind hier unterschiedliche Qualitätsmerkmale zu berücksichtigen, die es gegeneinander abzuwägen gilt. Während ich in meinem Beitrag stark auf Skalierbarkeit fokussiere, schicken Sie mit User Experience, Sicherheits- sowie Datenschutzaspekten weitere ins Rennen.

      Einmal angenommen es handelt sich bei dem Projekt um einen einfachen Newsletter. Hier wird es dem Anbieter hauptsächlich darum gehen, die E-Mail-Adresse und einige Basisdaten der Abonnenten zu erfassen. In diesem Fall treten die von Ihnen angesprochenen Sicherheitsbedenken hinsichtlich Zugriff durch den OAuth-Anbieter mit hoher Wahrscheinlichkeit in den Hintergrund. Schließlich sind diese Daten dem OAuth-Anbieter sowieso bekannt, sodass das Risiko eines Zugriffs durch diesen als eher unkritisch einzuschätzen ist. Eine direkte Integration ohne eigene Infrastruktur stellt hier daher aus meiner Sicht eine absolut valide Option dar.

      Sollte man jedoch im Rahmen seines Projektes zu einer Einschätzung nach einem höheren Schutzbedarf gelangen, ist dies sicherlich nicht gegeben. Klassische Beispiele, die hier immer wieder angeführt werden, finden sich im Versicherungswesen, Finanzverkehr, aber auch in Bereichen des E-Governments. In solchen Fällen muss meines Erachtens zwingend auf eine eigene Infrastruktur zurückgegriffen werden, falls man überhaupt zu der Einschätzung gelangt, dass eine Integration von Facebook und Co. möglich ist. Voraussetzung dafür ist natürlich immer, dass eine eigene Infrastruktur entsprechend sicher betrieben werden kann.

      Dies muss im Umkehrschluss natürlich nicht bedeuten, dass man auf eine gute User Experience verzichten muss. Identity Broker bieten hier gute Möglichkeiten der Integration einzelner OAuth-Anbieter und erlauben (zumindest technisch) auch Vertrauen jederzeit zu entziehen.
      Ergänzend bietet sich natürlich immer noch die Möglichkeit für einzelne Bereiche eine Mehrfaktor-Authentifizierung zu etablieren. Dies geht jedoch oftmals mit einer schlechteren User Experience einher.

      Wie Sie sehen, ist die Frage nicht einfach zu beantworten und Bedarf einer genauen Abwägung. Sollten Sie weiteren Wunsch nach Austausch zu diesem Thema haben, kommen Sie gerne nochmal auf mich zu.

      Viele Grüße
      Sven-Torben Janus

      Antworten

Schreibe einen Kommentar

Das könnte Dich auch noch interessieren

Software-Modernisierung: viele Wege führen nach Rom

Software-Modernisierung: viele Wege führen nach Rom

Bei der Modernisierung einer Anwendung sind viele Dinge zu berücksichtigen. Der erste Schritt auf dem Weg zu einer modernisierten Anwendung ...
Weiterlesen
CQRS und EventSourcing bei der DDD.Ruhr #5

CQRS und EventSourcing bei der DDD.Ruhr #5

Dankeschön Herzlichen Dank noch einmal an alle Teilnehmer meines Vortrags "Über Anatomie und Komplexität von CQRS und Event Sourcing" bei ...
Weiterlesen
Die Anatomie von Event Sourcing in Java

Die Anatomie von Event Sourcing in Java

In diesem zweiten Beitrag widme ich mich nun umgekehrt dem Event Sourcing, klammere dafür aber CQRS explizit aus. Das Ziel ...
Weiterlesen