2016-11-07 4 views
6

Kontext: Ich erstelle eine Cloud-Plattform, um mehrere Anwendungen mit SSO zu unterstützen. Ich benutze Keycloak zur Authentifizierung und Netflix Zuul für die Autorisierung (API Gateway) bis Keycloak Feder Sicherheitsadapter.Microservice zu Microservice Anrufe, Autorisierung von einer Warteschlange Nachricht

Jeder Microservice erwartet einen Authorization Header, der eine gültige JWT enthält, von der aus der Username (sub) zur Bearbeitung der Anfrage benötigt wird. Jeder Microservice-zu-Microservice-Aufruf sollte zuerst durch Netflix Zuul gehen und den Authorization-Header übergeben, um eine zustandslose Überprüfung beizubehalten. Diese Strategie ermöglicht es jedem Microservice zu wissen, wer der Benutzer (Sub) ist, der den Microservice indirekt anruft.

Problem/Frage 1: Was passiert, wenn ein Microservice aus einer Queue-Nachricht aufgerufen wird? Eine Idee, die ich hatte ist in der Warteschlange die Informationen in Bezug auf die Nachricht + userInfo zu speichern und einen dedizierten Microservice zur Verarbeitung dieser Art von Nachrichten zu erstellen. Bei diesem Ansatz sollte dieser spezielle Microservice die userInfo aus der Warteschlange lesen und die Nachricht verarbeiten .

AKTUALISIERUNG 1: Nach einer E-Mail-Antwort aus einem anderen Forum ist das Speichern der JWT in einer Warteschlange keine gute Idee, da sie leicht extrahiert werden kann.

Problem/Frage 2: Aber was, wenn der vorherige spezielle Micro geschieht will einen weiteren normalen Micro nennen, die eine JWT in einem Header erhalten erwarten? Sollte dieser spezielle Microservice selbst ein JWT erstellen, um sich als Benutzer auszugeben und die regulären Microservices anrufen zu können?

Eine andere Lösung, die ich dachte, war, den ursprünglichen JWT in der Warteschlange zu speichern, aber was passiert, wenn die Warteschlange später zum speziellen Microservice aufruft? Kurz nachdem das JWT nicht mehr gültig ist (es ist abgelaufen) und der aufgerufene Microservice die Anfrage ablehnen wird?

Mögliche Lösungen: (Stand per João Angelo Diskussion siehe unten)

Ich sollte die Anfragen von meinem Benutzer (Autorisierungscode Fluss) und meine Dienste (Client-Anmeldeinformationen gewähren) authentifizieren Beide Anfragen sollten Benutzerinformationen in der Payload enthalten. Wenn die Anfrage von dem Benutzer kommt, muss ich überprüfen, dass die Nutzlastbenutzerinformationen mit den JWT-Ansprüchen übereinstimmen. Wenn die Anfrage von einem Dienst kommt, muss ich nur auf diesen Dienst vertrauen (solange er unter meiner Kontrolle steht).

Ich werde sehr Ihre Hilfe zu schätzen wissen. Vielen Dank.

Antwort

5

Haftungsausschluss: Ich habe Keycloak nie verwendet, aber das Tag-Wiki sagt, dass es mit OAuth2 kompatibel ist, also vertraue ich diesen Informationen.


Bei einer sehr hohem Niveau Ansicht, Sie scheinen zwei Anforderungen zu haben:

  1. Aktionen durch einen Endbenutzer ausgelöst authentifizieren, während er Ihr System verwenden.
  2. Authentifizierungsaktionen, die von Ihrem System zu einem unbekannten Zeitpunkt ausgelöst wurden und bei denen kein Endbenutzer online sein muss.

Sie erfüllt bereits die erste, durch Authentifizierungssystem und basierend auf einem Token-Berufung ich genau das gleiche für den zweiten Punkt tun würde, wäre der einzige Unterschied, dass die Token auf Ihrem System ausgegeben würden mit Die OAuth2-Client-Anmeldeinformationen gewähren anstelle der anderen Gewährungen, die auf Szenarien ausgerichtet sind, in denen sich ein Endbenutzer befindet.

Client Credentials Grant

(Quelle: Client Credentials Grant)

In Ihrem Fall würde Keycloak die Rolle der Auth0 spielen und Ihre Client-Anwendungen sind Microservices, die verwendet Client Geheimnisse pflegen können sich in der Autorisierungs-Server zu authentifizieren und erhalten Zugriffstoken.

Eine Sache im Auge zu haben, ist, dass, wenn Ihr System für viel mehr als die Authentifizierung und Autorisierung auf dem sub Anspruch beruht, dann können Sie einige Anpassungen vornehmen müssen. Zum Beispiel habe ich Systeme gesehen, bei denen die Ausführung von Aktion A erforderlich war, um zu wissen, dass sie an Benutzer X und Y gerichtet war, aber die Nutzlast für die Aktion nur Benutzer Y empfing und angenommener Benutzer X war der aktuelle authentifizierte Prinzipal. Dies funktioniert gut, wenn alles synchron ist, aber das bloße Umschalten der Nutzlast zum Angeben beider Benutzer würde bedeuten, dass die Aktion asynchron von einem systemauthentifizierten Prinzipal ausgeführt werden könnte.

+0

Hallo João, ich verstehe, so, 1) die Microservices sollte immer ein JWT entweder vom Benutzer oder einem anderen Dienst. Ich habe gerade den Test gemacht, und festgestellt, dass einige der Unterschiede zwischen einem JWT für einen Microservice im Vergleich zu einem Benutzer keine Ansprüche enthält, und es enthält ein zusätzliches Feld "clientId", so dass etwa, wenn das JWT enthält ein " clientId "ist kein Benutzer, sondern ein Dienst. Oder ich kann mich auf das Feld "aud" verlassen, wenn "aud" dem Clientnamen entspricht, um Benutzer zu authentifizieren, es ist ein Benutzer, wenn nicht, ist ein anderer Dienst. –

+0

2) Es scheint, dass ich immer die userId in der Nutzlast senden muss, damit der Dienst die Anforderungen auf transparente Weise (Dienst oder Benutzeranruf) verarbeiten kann, wenn ich feststelle, dass der Anruf von einem Benutzer entweder "aud" oder ist "clientId" Ich kann das Payload-Feld mit dem "sub-" oder "preferred_username" überprüfen, um sicherzustellen, dass der Wert der Payload dem Benutzer entspricht, der die Aktion ausführt. Aber im Fall eines Dienstes muss ich nur auf Benutzer vertrauen, der in der Nutzlast spezifiziert ist? –

+0

Ja, das wäre ein Ansatz, validieren Sie die Eingabe, wenn es von den Benutzern kommt, um sicherzustellen, dass sie nicht versuchen, andere Benutzer zu fälschen und vertrauen, wenn es von Ihren eigenen Diensten kommt. Unter der Annahme, dass alle Microservices unter Ihrer Kontrolle stehen, scheint dies ein geeigneter Ansatz zu sein. Es scheint auch einfacher zu sein als das Speichern von Zugriffstoken und/oder Aktualisierungstoken, damit Sie den Aufruf später auch dann durchführen können, wenn der Benutzer offline ist. –

0

Eine allgemeine Einstellung ist eine API gateway, die alle eingehenden Anfragen von ihrer JWT überprüfen. Das API-Gateway validiert die Signatur des JWT (oder entschlüsselt es für verschlüsselte JWTs), überprüft die Ablaufzeit usw. und extrahiert die Bereiche und die Benutzer-ID (Sub-ID) daraus.

Anschließend vergleicht es die Bereiche mit einer Reihe von definierten Bereichen für jeden Microsoft-Dienst, und wenn der Bereich den Benutzer- (Betreff-) Zugriff bereitstellt, wird die Anforderung an den Mikroservice weitergeleitet. Die Benutzer-ID (Sub in der JWT), zusammen mit anderen benötigten Informationen in der JWT gespeichert ist in benutzerdefinierten Anfragen Header wie X-IGNACIO-SUBJECT