SOA / Microservices: Wie gehe ich bei der dienstübergreifenden Kommunikation mit Autorisierungen um?

18

Vordergrund

Wir wechseln von einer monolithischen Plattform zu einer serviceorientierteren Architektur. Wir wenden sehr grundlegende DDD-Prinzipien an und teilen unsere Domäne über verschiedene begrenzte Kontexte auf. Jede Domain wird verteilt und macht einen Service über eine Web-API (REST) ​​verfügbar.

Aufgrund der Art unseres Geschäfts haben wir Dienstleistungen wie Buchungen , Dienstleistungen , Kunden , Produkte usw.

Wir haben auch einen Identity Server (basierend auf Thinktecture Identity Server 3) eingerichtet, dessen Hauptaufgabe darin besteht:

  • Zentralisieren Sie die Authentifizierung (mit den von ihr ausgegebenen Anmeldeinformationen)
  • Fügen Sie Ansprüche in die Token ein, wie z. B .: die Bereiche des Kunden (gemäß Kunden, in dem die Anwendung die Anforderung ausführt), Kunden-ID (gemäß Kunden, in dem ich die Person bezeichne, die die Anwendung verwendet).

Wir haben auch die Rolle eines API-Gateways eingeführt, das den externen Zugriff auf unsere Dienste zentralisiert. API Gateway bietet Funktionen, für die keine umfassenden Kenntnisse der internen Domänen erforderlich sind, z.

  • Reverse Proxy: Leitet eingehende Anfragen an den entsprechenden internen Dienst weiter
  • Versionierung: Eine Version des API-Gateways ist verschiedenen Versionen der internen Services zugeordnet
  • Authentifizierung: Client-Anforderungen enthalten das vom Identity Server ausgegebene Token, und das API-Gateway überprüft das Token (stellen Sie sicher, dass der Benutzer derjenige ist, der es angibt).
  • Drosselung: Begrenzen Sie die Anzahl der Anforderungen pro Client

Genehmigung

Was die Autorisierung betrifft, wird dies nicht im API-Gateway, sondern in den internen Diensten selbst verwaltet. Derzeit führen wir zwei Arten von Berechtigungen durch:

  • Autorisierung basierend auf Client-Gültigkeitsbereichen. Beispiel: Ein Client (externe Anwendung, die unsere APIs verwendet) benötigt den Bereich "Buchungen", um auf die API-Endpunkte des Buchungsservice zuzugreifen
  • Autorisierung basierend auf dem Kunden. Beispiel: Nur wenn ein Kunde (physische Person , die die Anwendung verwendet wird ) ist ein Teilnehmer einer Buchung kann den Endpunkt GET Zugang / Buchungen aus dem Buchungen Service

Um die Autorisierung in den internen Diensten handhaben zu können, leitet das API - Gateway das Token (beim Weiterleiten der Anforderung an den internen Dienst) einfach weiter, das sowohl Informationen über den Client (die Anwendung, die die Anforderung ausführt) als auch den Kunden als Anspruch enthält (in Fälle, in denen eine Person in der Client-Anwendung angemeldet ist).

Problembeschreibung

Soweit so gut, bis wir die dienstübergreifende Kommunikation eingeführt haben (einige Dienste können mit anderen Diensten kommunizieren, um Daten zu erhalten).

Frage

Wie gehen wir bei der dienstübergreifenden Kommunikation mit der Autorisierung um?

Optionen berücksichtigt

Um die verschiedenen Optionen zu diskutieren, verwende ich das folgende Beispielszenario:

  • Wir haben eine externe Anwendung namens ExternalApp , die auf unsere API zugreift ( ExternalApp kann als Client betrachtet werden ), um den Buchungsfluss aufzubauen
  • ExternalApp benötigt Zugriff auf den Buchungsservice , daher erteilen wir der ExternalApp den Bereich "Buchungen".
  • Intern (dies ist für die ExternalApp völlig transparent ) greift der Buchungsdienst auf den Dienst " Dienste" zu, um die Standarddienste einer Buchung wie Flüge, Versicherungen oder Mietwagen zu erhalten

Bei der internen Diskussion dieses Problems tauchten verschiedene Optionen auf, wir sind uns jedoch nicht sicher, welche Option die beste ist:

  1. Wenn Bookings mit Services kommuniziert , sollte es einfach das ursprüngliche Token weiterleiten, das er vom API-Gateway erhalten hat (was darauf hinweist, dass der Client die ExternalApp ist ).
    • Auswirkungen: Möglicherweise müssen Sie der ExternalApp Bereiche zuweisen , die nicht gewährt werden sollten. Beispiel: ExternalApp muss möglicherweise sowohl den Bereich "Buchungen" als auch den Bereich "Dienste" aufweisen, während möglicherweise nur der Bereich "Buchungen" ausreicht
  2. Wenn Bookings mit Services kommuniziert , wird ein Token weitergeleitet, das angibt, dass der Client jetzt zu Bookings (anstelle der ExternalApp ) geworden ist. Außerdem wird ein Anspruch hinzugefügt , der angibt, dass Bookings die Identität der ExternalApp des ursprünglichen Clients annimmt
    • Durch das Einbeziehen der Information, dass der Original-Client die ExternalApp ist, könnte der Services- Service auch logisch vorgehen, wie das Herausfiltern einiger Services in Abhängigkeit vom ursprünglichen Anrufer (z. B. sollten wir für interne Apps alle Kämpfe zurückgeben, für externe Apps nur einige).
  3. Dienste sollten nicht miteinander kommunizieren (daher sollten wir uns dieser Frage nicht einmal stellen)

Vielen Dank im Voraus für Ihre Eingabe.

Josep Serra
quelle
1
Wie haben Sie dieses Problem gelöst? Wir sind in einer ähnlichen Situation.
Varun Mehta
+1: Ich bin daran interessiert, wie Sie Ihr Problem endlich lösen.
Dypso

Antworten:

3

Ich empfehle Ihnen einen internen Kommunikationskanal zwischen den Mikrodiensten.

Zum Beispiel, um einen Nachrichtenbroker wie RabbitMQ intern zum Senden / Empfangen oder Veröffentlichen / Abonnieren der Nachrichten zwischen Microservices zu verwenden.

Dann ist Ihr erster Endbenutzer, der dem Service "in Ihrem Beispiel der Buchungsservice" gegenübersteht, für die Validierung des Tokens verantwortlich und ermächtigt den Kunden, diese spezielle Operation durchzuführen, indem er möglicherweise mit IdentityServer kommuniziert.

Anschließend wird über Message Broker mit dem Dienst "Dienste" kommuniziert. In diesem Fall muss das Token nicht erneut überprüft werden.

Ich denke, dieses Modell wird einfacher und bietet eine bessere Leistung.

Wahid Bitar
quelle