Sollten Microservices Nutzer sein?

13

Wir versuchen herauszufinden, wie Benutzer in einer Microservice-Architektur am besten autorisiert werden können, während sichergestellt wird, dass Microservices nur über eingeschränkte Berechtigungen verfügen. Unsere Architektur verwendet einen zentralen Berechtigungsservice für die Ausgabe von JWT-Token.

Wir haben folgende Anforderungen:

  1. Benutzer sollten auf die Ausführung bestimmter Rollen beschränkt sein. Zum Beispiel sollte ein Benutzer nur in der Lage sein, Inhalte zu erstellen, zu ändern oder zu lesen, die er besitzt.

  2. Microservices sollten nur auf die erforderlichen Berechtigungen beschränkt werden. Beispielsweise sollte es einem Mikrodienst, der nur Daten von einem anderen Dienst lesen muss, ausdrücklich untersagt sein, Daten in diesen Dienst zu schreiben.

Angenommen, wir haben ein System, mit dem Benutzer Bilder zu einem Image Store-Dienst hochladen können. Wir haben einen Tagging-Service, der Bilder automatisch mit einem Ort markiert. Benutzer können nur ihre eigenen Bilder CRUD. Der Markierungsdienst kann jedes Bild aus dem Bildspeicherdienst lesen, sollte jedoch nicht in der Lage sein, Änderungen / Löschungen vorzunehmen.

Was ist ein guter Weg, um dies mit JWT-Token zu erreichen? Einige Lösungen, die wir besprochen haben, sind:

  1. Der Image Store-Dienst stellt zwei APIs zur Verfügung, eine, die extern verfügbar ist (Zugriff auf Benutzer-CRUD) und eine, die intern verfügbar ist (schreibgeschützten internen Zugriff). Scheint unflexibel - was ist, wenn ein anderer interner Dienst Lese- / Schreibzugriff auf alle Bilder benötigt (z. B. eines, das explizite Bilder automatisch löscht)?

  2. Wir haben zwei Berechtigungen im JWT des Benutzers eingerichtet, eine ist CRUD_OwnImages, die andere ist READ_ForAnalysis. Der Markierungsdienst kann feststellen, ob der Benutzer über die Berechtigung READ_ForAnalysis verfügt, und in diesem Fall die entsprechende Anforderung stellen. Wir haben einen weiteren Microservice, der prüft, ob der Benutzer CRUD_OwnImages für CRUD-Operationen an den eigenen Bildern des Benutzers hat. Auf diese Weise ist jeder Mikrodienst verpflichtet, sicherzustellen, dass der Benutzer auf die von ihm gewünschten Aktionen beschränkt ist. Der Abbildspeicher hat bei diesem Ansatz keine Möglichkeit, jeden Mikrodienst einzuschränken, sodass er potenziell unauffällig und fehleranfällig ist.

  3. Wir geben dem Markierungsmikroservice einen eigenen Benutzer mit READ_ForAnalysis als Erlaubnis. Wenn der Markierungsdienst dann Bilder aus dem Bildspeicher anfordert, erhält er Zugriff auf diese, es ist jedoch verboten, sie zu ändern. Der Benutzer des Benutzers hat nur die Berechtigung CRUD_OwnImages, sodass er nur seine Bilder vom Frontend abrufen und darauf zugreifen kann. Wenn ein anderer Dienst CRUD für alle Daten benötigt, können wir ihm CRUD_AllData oder ähnliches geben. Wir mögen diesen Ansatz, da jeder Dienst jetzt für seine eigenen Daten verantwortlich ist (anstatt dass diese Logik über mehrere Dienste hinweg dupliziert wird). Aber was ist, wenn für den Dienst sowohl Benutzer- als auch Microservice-Berechtigungen erforderlich sind? Können wir zwei JWT-Token (sowohl den Benutzer- als auch den Mikrodienst) sicher senden? Gibt es eine Möglichkeit, Berechtigungen sicher zu kombinieren und diese zu senden? z.B

Das Problem wird verschlimmert, wenn die Benutzerinformationen weiter stromabwärts benötigt werden (2 oder 3 Mikrodienste entfernt). Gehen wir nur davon aus, dass es an den einzelnen Mikrodiensten liegt, sich auf die von ihnen benötigten Aktionen zu beschränken und dies nicht explizit zu machen?

awr
quelle
1
Sind Sie der einzige Entwickler dieser Microservices, oder schreiben andere Unternehmen / Organisationen / Abteilungen (z. B. alles mit einer Sicherheitsgrenze) ebenfalls Microservices für Ihr System?
Robert Harvey
1
Es ist sehr wahrscheinlich, dass das System von anderen Diensten überwacht wird, und wir möchten diesbezüglich einen Entwurf erstellen.
am

Antworten:

6

Im Allgemeinen sollten so viele Operationen wie möglich an einen echten menschlichen Benutzer gebunden sein. Sie zwingt die Benutzer zur ordnungsgemäßen Authentifizierung, drängt auf eine einheitliche Autorisierungsstrategie und ist ein wichtiger Bestandteil der Bereitstellung eines zusammenhängenden Prüfpfads.

Und im Allgemeinen gibt es drei Arten von Szenarien mit Microservices:

1. Der Benutzer kommt herein, lädt ein Foto hoch und muss markiert werden. Groß. Der Fotodienst kann das JWT einfach an den Markierungsdienst weiterleiten (oder umgekehrt, je nach Richtung Ihrer Abhängigkeit). Wenn der Benutzer keine Berechtigung für die Unteroperation hat, ergreifen Sie die entsprechende Maßnahme (laden Sie das Foto möglicherweise ohne Markierung hoch) , möglicherweise den Fehler zurückgeben, möglicherweise noch etwas).

2. Der Benutzer kommt herein, lädt ein Foto hoch und es muss markiert werden ... aber nicht jetzt. Cool. Sie bearbeiten das Foto jetzt wie gewohnt. Später, wenn das Tagging auftritt (Ereignis- / Nachrichtenbehandlung, CQRS-Befehlsbearbeitung, einige periodische Jobbearbeitungen, was auch immer), gibt der Tagging-Dienst die Identität des Benutzers wieder (höchstwahrscheinlich durch Verwendung eines gemeinsamen Geheimnisses, um eine benutzerdefinierte JWT von auth anzufordern) und führt dies dann aus die Unteroperation im Namen des ursprünglichen Anforderers (mit all ihren Berechtigungen und Einschränkungen). Diese Methode hat das übliche Problem mit asynchronen Vorgängen, bei denen es schwierig ist, dem Benutzer Fehler zurückzugeben, wenn die Dinge nicht reibungslos verlaufen. Wenn Sie dieses Muster jedoch für dienstübergreifende Vorgänge verwenden, haben Sie das bereits gelöst.

3. Einige Subsysteme müssen Aufgaben außerhalb des Kontexts eines Benutzers ausführen. Vielleicht hast du jede Nacht eine Aufgabe, um alte Bilder zu archivieren. Vielleicht müssen Ihre Tags konsolidiert werden ... In diesem Fall möchten Sie wahrscheinlich, dass jeder dieser Akteure einen eigenen Pseudo-Benutzer mit eingeschränkten Berechtigungen und einer eindeutigen ID für den Audit-Trail hat.

Welche Methode Sie verwenden müssen, hängt von Ihrem Szenario, Ihren Anforderungen und Ihrer Risikotoleranz ab. Und dies sind natürlich nur unvollständige Verallgemeinerungen für breite Striche.

Im Allgemeinen sollten Microservices selbst jedoch nach Möglichkeit keine Benutzer sein.

Telastyn
quelle
1
Sind Ihr erster und letzter Absatz nicht widersprüchlich?
Robert Harvey
1
Nein? Vorgänge sollten an einen Benutzer gebunden sein. Microservices selbst sind keine Benutzer ... Ich werde klarstellen.
Telastyn
1
Ich bin auf eine Lösung für das Problem gestoßen, die Folgendes vorschlug: Definieren Sie einen Bereich für jeden Mikrodienst, indem Sie in seinem Zugriffstoken angeben, auf welche Endpunkte zugegriffen werden kann. Übergeben Sie auch das JWT-ID-Token des Benutzers als anderen Header. Auf diese Weise können wir sowohl Microservices als auch Benutzer einschränken (Tiefenverteidigung). Kapitel 10 von manning.com/books/microservices-in-net-core
am
Szenario 3 ist interessant, weshalb wir teilweise entschieden haben, dass Benutzer Microservices sein sollten. Aber sieht so aus, kann eher eine Ausnahme als die Regel sein.
am