Tiefen Einblick in die Authentifizierung in Microservices
Zexuan Luo / Shirui Zhao
December 23, 2022
Was ist ein Authentifizierungsdienst?
Authentifizierung ist die Überprüfung der Identität eines Benutzers, um ihm Zugriff und die notwendigen Berechtigungen zur Nutzung des Systems zu gewähren. Der Dienst, der diese Funktion bereitstellt, ist der Authentifizierungsdienst. In einer traditionellen monolithischen Softwareanwendung geschieht dies alles innerhalb derselben Anwendung, aber in einer Microservices-Architektur besteht das System aus mehreren Diensten. Jeder Microservice hat in einer solchen Architektur seine eigenen Aufgaben, sodass die Implementierung des Autorisierungs- und Authentifizierungsprozesses für jeden Microservice separat nicht vollständig funktioniert.
Dieser Artikel vergleicht die traditionelle Authentifizierung mit der Microservice-Authentifizierung. Und zeigt die Veränderungen in der Authentifizierung, die durch die Veränderungen in der Architektur entstehen. Schließlich analysieren wir die verschiedenen Authentifizierungsdienste in der Microservice-Architektur und ihre Vor- und Nachteile in ihren Implementierungen.
Authentifizierungsdienst in der traditionellen Architektur
In den Anfängen, als Unternehmen Dienste entwickelten, wurden alle Funktionen in derselben Anwendung implementiert. Wir nennen dieses Modell "monolithisch", um es von der aktuellen, eher mainstreamigen "Microservice"-Architektur zu unterscheiden.
Eine monolithische Anwendung besteht aus einer einzigen unteilbaren Einheit. Sie wird normalerweise unabhängig von separaten Geschäftsbereichen entwickelt und bei der Bereitstellung in derselben Umgebung kombiniert. All dies ist eng integriert, um alle Funktionalitäten in einer Einheit bereitzustellen. Diese Einheit verfügt über alle benötigten Ressourcen. Der Vorteil einer monolithischen Anwendung ist, dass sie einfach zu implementieren und zu iterieren ist. Sie eignet sich für unabhängigere Unternehmen mit weniger Geschäftsbereichen.
Da die von Unternehmen entwickelten Geschäfte immer komplexer werden, werden wir feststellen, dass einzelne Dienste den Anforderungen der schnellen Iteration im realen Leben nicht mehr gerecht werden können. Wir müssen dieses riesige System aufteilen und sicherstellen, dass die Aufrufe zwischen bestehenden Funktionen normal durchgeführt werden können. Um dieses Problem zu lösen, entstand ESB (Enterprise Service Bus).
Der "Enterprise Service Bus" ist eine Pipeline, die verschiedene Unternehmensdienste verbindet. Die Existenz von ESB dient dazu, verschiedene Dienste mit unterschiedlichen Protokollen zu integrieren. ESB bietet Dienste wie die Übersetzung und das Routing von Client-Anfragen, sodass verschiedene Dienste leicht miteinander verbunden werden können. Wie der Name schon sagt, entlehnt sein Konzept das Kommunikationsmodell aus dem Prinzip der Computerarchitektur - Bus, alle Systeme, die mit externen Systemen kommunizieren müssen, verbinden sich mit ESB. Sie können das bestehende System nutzen, um ein neues lose gekoppeltes heterogenes verteiltes System aufzubauen.
ESB hat Anfragen übersetzt und geroutet, sodass verschiedene Dienste miteinander kommunizieren können. Die traditionelle ESB-Dienstaufrufmethode besteht darin, dass der Aufrufer jedes Mal zuerst über den zentralen ESB zum Dienst geroutet werden muss.
Monolithische Architektur
Benutzerauthentifizierung und Sitzungsverwaltung sind relativ einfach: Authentifizierung und Autorisierung erfolgen in derselben Anwendung, normalerweise unter Verwendung eines sitzungsbasierten Authentifizierungsschemas. Sobald die Authentifizierung erfolgt ist, wird eine Sitzung erstellt und auf dem Server gespeichert. Jede Komponente kann darauf zugreifen und sie verwenden, um nachfolgende Anfragen zu benachrichtigen und zu autorisieren. Die Sitzungs-ID wird an den Client gesendet und verwendet, um alle nachfolgenden Anfragen mit der aktuellen Sitzung zu verknüpfen.
ESB-Architektur
Unter der ESB-Architektur werden alle Prozesse zwischen Diensten über den ESB-Bus verarbeitet. Da die ESB-Architektur aus der monolithischen Architektur abgeleitet ist, hat sich die Authentifizierungsmethode im Vergleich zur monolithischen Architektur nicht geändert.
Authentifizierungsdienst in der Microservice-Architektur
Die Migration von einer monolithischen Architektur zu einer Microservice-Architektur bietet viele Vorteile. Aber als verteilte Architektur hat die Microservice-Architektur eine größere Angriffsfläche, was die gemeinsame Nutzung des Benutzerkontexts erschwert. Daher sind unter der Microservice-Architektur verschiedene Authentifizierungsdienste erforderlich, um auf größere Sicherheitsherausforderungen zu reagieren.
Wir können die Authentifizierungsdienste unter der Microservice-Architektur in die folgenden drei Kategorien einteilen:
- Implementierung der Authentifizierung auf jedem Microservice
- Implementierung der Authentifizierung über einen Authentifizierungsdienst
- Implementierung der Authentifizierung über das API-Gateway
Jeder Ansatz hat seine spezifischen Vor- und Nachteile.
Implementierung der Authentifizierung auf jedem Microservice
Da jeder Microservice aus der monolithischen Architektur aufgeteilt wurde, ist eine natürliche Übergangsphase zur Implementierung der Authentifizierung, dass jeder Microservice sie selbst implementiert.
Jeder Microservice muss seine eigenen unabhängigen Sicherheitsgarantien implementieren, die an jedem Einstiegspunkt durchgesetzt werden. Dieser Ansatz befähigt Microservice-Teams, autonome Entscheidungen über die Implementierung ihrer Sicherheitslösungen zu treffen. Dieser Ansatz hat jedoch mehrere Nachteile:
- Sicherheitslogik muss in jedem Microservice wiederholt implementiert werden. Dies führt zu Code-Duplikation zwischen Diensten.
- Es lenkt das Entwicklungsteam davon ab, sich auf ihren Hauptdienst zu konzentrieren.
- Jeder Microservice ist von Benutzerauthentifizierungsdaten abhängig, die er nicht besitzt.
- Schwierig zu warten und zu überwachen.
Eine Option, um diese Lösung zu verbessern, ist die Verwendung einer gemeinsamen Authentifizierungsbibliothek, die auf jedem Microservice geladen wird. Dies verhindert Code-Duplikation, und das Entwicklungsteam konzentriert sich nur auf ihre Geschäftsdomäne. Es gibt jedoch immer noch Mängel, die diese Verbesserung nicht lösen kann. Da die gemeinsame Authentifizierungsbibliothek immer noch entsprechende Benutzeridentitätsdaten haben muss, ist es auch notwendig sicherzustellen, dass jeder Microservice die exakte Version der Authentifizierungsbibliothek verwendet. Die gemeinsame Authentifizierungsbibliothek ähnelt eher dem Ergebnis einer schlechten Dienstaufteilung.
Vorteile: schnelle Implementierung, starke Unabhängigkeit
Nachteile: Code-Duplikation zwischen Diensten; Verletzung des Single-Responsibility-Prinzips; Schwierigkeiten bei der Wartung
Implementierung der Authentifizierung über einen Authentifizierungsdienst
Da es schwierig ist, dass jeder Microservice die Authentifizierung selbst implementiert, und die Verwendung einer gemeinsamen Authentifizierungsbibliothek gegen die ursprüngliche Absicht der Microservice-Aufteilung verstößt, kann die gemeinsame Authentifizierungsbibliothek zu einem dedizierten Authentifizierungsdienst aufgewertet werden?
In diesem Fall wird der gesamte Zugriff von demselben Dienst kontrolliert, ähnlich der Authentifizierungsfunktion in einer monolithischen Anwendung. Jeder Geschäftsdienst muss eine separate Autorisierungsanfrage an das Zugriffssteuerungsmodul senden, wenn er eine Operation durchführt.
Dieser Ansatz verlangsamt jedoch den Dienst und erhöht die Interkonnektivität zwischen Diensten. Und jeder Microservice wird von diesem "einzigen" Authentifizierungsdienst abhängig sein. Er ist anfällig für einen Single Point of Failure und eine Kettenreaktion, die zusätzlichen Schaden verursacht.
Vorteile: Jeder Microservice hat eine einzige Verantwortung, und die Authentifizierung ist zentralisiert
Nachteile: Single Point of Failure; erhöhte Anforderungslatenz
Implementierung der Authentifizierung über das API-Gateway
Bei der Migration zu einer Microservices-Architektur ist eine Frage, die beantwortet werden muss, wie die Microservices miteinander kommunizieren. Der oben erwähnte ESB ist ein Ansatz, aber häufiger wird ein API-Gateway eingesetzt. Das API-Gateway ist ein einziger Einstiegspunkt für alle Anfragen. Es bietet Flexibilität, indem es als zentrale Schnittstelle für die Nutzung dieser Microservices fungiert. Ein Microservice, der auf andere Microservices zugreifen muss (von nun an werden wir ihn als "Client" bezeichnen, um ihn von dem Microservice, auf den er zugreift, zu unterscheiden), hat keinen direkten Zugriff auf Dienste, sondern sendet die Anfrage an das API-Gateway, das für das Routing des Clients zum Upstream-Dienst verantwortlich ist.
Da alle Anfragen zuerst über das API-Gateway gehen müssen, ist es ein ausgezeichneter Kandidat für die Durchsetzung von Authentifizierungsproblemen. Es reduziert die Latenz (Aufrufe von Authentifizierungsdiensten) und stellt sicher, dass der Authentifizierungsprozess in der gesamten Anwendung konsistent ist.
Zum Beispiel können wir mit dem jwt-auth-Plugin von APISIX die Authentifizierung auf dem Gateway implementieren.
- Wir müssen mehrere Benutzeridentitätsinformationen (Name, Schlüssel usw.) auf APISIX konfigurieren.
- Gemäß dem gegebenen Benutzerschlüssel eine Signaturanfrage an APISIX initiieren, um das JWT-Token des Benutzers zu erhalten.
- Dann, wenn der Client auf einen Upstream-Dienst zugreifen muss, bringt er das JWT-Token mit, und APISIX fungiert als API-Gateway, um diesen Zugriff zu proxen.
- Schließlich wird APISIX die Authentifizierungsoperation mit dem JWT-Token abschließen.
Natürlich hat alles Vor- und Nachteile, und keine Technologie ist ohne Mängel. Die Verwendung eines API-Gateways zur Authentifizierung hat immer noch einige Probleme. Die Lösung dieses Problems auf dem Gateway ist weniger sicher als die Authentifizierung innerhalb jedes Microservices. Zum Beispiel, wenn das API-Gateway kompromittiert wird, werden alle Microservices dahinter exponiert. Aber das Risiko ist relativ. Im Vergleich zum einzelnen Authentifizierungsdienst ist das Problem der Verwendung eines API-Gateways mild.
Vorteile: Effektiver Schutz der Backend-Microservices; Microservices müssen keine Authentifizierungslogik handhaben
Nachteil: Single Point of Failure
Zusammenfassung
In verschiedenen Szenarien benötigen wir unterschiedliche Authentifizierungsschemata. In einer monolithischen Anwendung erfolgt die Authentifizierung innerhalb derselben Anwendung, und der Server speichert alle Sitzungen. In der Ära der Microservices haben sich monolithische Anwendungen zu verteilten Diensten entwickelt, und die traditionellen Authentifizierungsmethoden gelten nicht mehr. In der Microservice-Architektur haben wir drei Authentifizierungsmethoden zur Auswahl:
- Implementierung der Authentifizierung auf jedem Microservice
- Implementierung der Authentifizierung über einen Authentifizierungsdienst
- Implementierung der Authentifizierung über das API-Gateway
Jede Option hat ihre eigenen Vor- und Nachteile, die je nach den Umständen detailliert analysiert werden müssen.