Autorisierungs- und Authentifizierungssystem für Mikrodienste und Verbraucher

15

Wir planen, unser Unternehmenssystem in ein auf Mikroservices basierendes System umzugestalten. Diese Mikrodienste werden von unseren firmeninternen Anwendungen und bei Bedarf von Drittanbietern genutzt. Eins für Buchung, eins für Produkte etc.

Wir sind uns nicht sicher, wie wir mit Rollen und Bereichen umgehen sollen. Die Idee ist, drei grundlegende Benutzerrollen wie Admins, Agents und Endbenutzer zu erstellen und den Consumer-Apps bei Bedarf die Feinabstimmung der Bereiche zu ermöglichen.

  • Administratoren können standardmäßig alle Ressourcen (für ihr Unternehmen) erstellen, aktualisieren, lesen und löschen.
  • Agenten können Daten für ihr Unternehmen erstellen, aktualisieren und lesen.
  • Endbenutzer können Daten erstellen, aktualisieren, löschen und lesen, jedoch nicht auf dieselben Endpunkte wie Agenten oder Administratoren zugreifen. Sie können auch Daten erstellen oder ändern, nur nicht auf derselben Ebene wie Agenten oder Administratoren. Beispielsweise können Endbenutzer ihre Kontoinformationen aktualisieren oder lesen, genauso wie der Agent dies für sie tun kann, sie können jedoch keine Administratornotizen anzeigen oder aktualisieren.

Angenommen, Agenten können standardmäßig jede Ressource für ihr Unternehmen erstellen, lesen und aktualisieren. Dies ist der maximale Bereich, der für ihr Token / ihre Sitzung angefordert werden kann. Entwickler von Clientanwendungen (API-Consumer-Anwendungen) haben jedoch entschieden, dass einer ihrer Agenten dies kann Lesen und erstellen Sie nur bestimmte Ressourcen.

Ist es eine bessere Praxis, dies in unserer internen Sicherheit zu behandeln und diese Daten in unsere Datenbank schreiben zu lassen, oder lassen Sie die Clients dies intern tun, indem Sie ein Token mit geringerem Umfang anfordern, und schreiben, welcher Agent welchen Umfang in ihrer Datenbank hat ? Auf diese Weise müssten wir nur Token-Bereiche verfolgen.

Der Nachteil dabei ist, dass unser Team auch in unseren internen Anwendungen genau abgestimmte Zugriffsmechanismen erstellen muss.

Mit dieser Denkweise sollten Mikrodienste und ihr Autorisierungssystem nicht mit den Kundenbedürfnissen belastet werden, da sie nur Verbraucher sind und nicht Teil des Systems (auch wenn einige dieser Verbraucher unsere eigenen internen Apps sind).

Ist diese Delegation ein guter Ansatz?

Robert
quelle

Antworten:

14

Authentifizierung und Autorisierung sind immer gute Themen

Ich werde versuchen, Ihnen zu erklären, wie wir mit Berechtigungen im aktuellen mandantenfähigen Dienst, den ich arbeite, umgehen. Die Authentifizierung und Autorisierung erfolgt auf Token-Basis unter Verwendung des offenen JSON-Web-Token-Standards. Der Dienst stellt eine REST-API bereit, auf die jeder Client (Web-, Mobil- und Desktopanwendungen) zugreifen kann. Wenn ein Benutzer erfolgreich authentifiziert wurde, stellt der Dienst ein Zugriffstoken bereit, das bei jeder Anforderung an den Server gesendet werden muss.

Lassen Sie mich einige Konzepte vorstellen, die wir basierend darauf verwenden, wie wir Daten auf der Serveranwendung wahrnehmen und behandeln.

Ressource : Es handelt sich um eine beliebige Einheit oder Gruppe von Daten, auf die ein Client über den Dienst zugreifen kann. Allen Ressourcen, die wir kontrollieren möchten, weisen wir einen einzelnen Namen zu. Wenn wir beispielsweise die nächsten Endpunktregeln haben, können wir sie wie folgt benennen:

product

/products
/products/:id

payment

/payments/
/payments/:id

order

/orders
/orders/:id
/orders/:id/products
/orders/:id/products/:id

Nehmen wir also an, dass wir bisher drei Ressourcen in unserem Dienst haben. product, paymentUnd order.

Aktion : Dies ist eine Operation, die für eine Ressource ausgeführt werden kann, z. B. Lesen, Erstellen, Aktualisieren, Löschen usw. Es muss sich nicht nur um die klassischen CRUD-Operationen handeln. Sie können beispielsweise eine Aktion mit dem Namen followhaben, wenn Sie möchten einen Dienst verfügbar machen, der Informationen mithilfe von WebSockets weitergibt.

Fähigkeit : Die Fähigkeit, actionan einer resource. Zum Beispiel; Produkte lesen, Produkte erstellen usw. Es handelt sich im Grunde genommen nur um ein Ressourcen- / Aktionspaar. Sie können aber auch einen Namen und eine Beschreibung hinzufügen.

Rolle : Eine Reihe von Fähigkeiten, die ein Benutzer besitzen kann. Beispielsweise kann eine Rolle Cashierdie Fähigkeiten "Zahlung lesen", "Zahlung erstellen" oder Sellerdie Fähigkeiten "Produkt lesen", "Bestellung lesen", "Bestellung aktualisieren", "Bestellung löschen" haben.

Schließlich kann einem Benutzer verschiedene Rollen zugewiesen werden.


Erläuterung

Wie ich bereits sagte, verwenden wir JSON-Web-Token und die Fähigkeiten, die ein Benutzer besitzt, werden in der Nutzlast des Tokens deklariert. Nehmen wir also an, wir haben einen Benutzer mit den Rollen Kassierer und Verkäufer gleichzeitig für ein kleines Einzelhandelsgeschäft. Die Nutzlast sieht folgendermaßen aus:

{
    "scopes": {
        "payment": ["read", "create"],
        "order": ["read", "create", "update", "delete"]
    }
}

Wie Sie im scopesClaim sehen können, geben wir nicht den Namen der Rollen (Kassierer, Verkäufer) an, sondern nur die Ressourcen und die damit verbundenen Aktionen. Wenn ein Client eine Anforderung an einen Endpunkt sendet, sollte der Dienst prüfen, ob das Zugriffstoken die erforderliche Ressource und Aktion enthält. Beispielsweise ist eine GETAnforderung an den Endpunkt /payments/88erfolgreich, eine DELETEAnforderung an denselben Endpunkt muss jedoch fehlschlagen.


  • Wie die Ressourcen gruppiert und benannt werden und wie die Aktionen und Fähigkeiten definiert und benannt werden, entscheiden die Entwickler.

  • Welche Rollen und welche Fähigkeiten diese Rollen haben, entscheiden die Kunden.


Natürlich müssen Sie der Nutzlast zusätzliche Eigenschaften hinzufügen, um den Benutzer und den Kunden (Mandanten) zu identifizieren, der das Token ausgestellt hat.

{
    "scopes": {
        ...
    },
    "tenant": "acme",
    "user":"coyote"
}

Mit dieser Methode können Sie den Zugriff eines beliebigen Benutzerkontos auf Ihren Dienst optimieren. Und das Wichtigste ist, dass Sie keine verschiedenen vordefinierten und statischen Rollen wie Admin, Agents und Endbenutzer erstellen müssen, wie Sie in Ihrer Frage dargelegt haben. Ein Super User wird ein Benutzer, der ein besitzt rolemit allen resourcesund actionsihm dem Dienst zugewiesen.

Was ist, wenn es 100 Ressourcen gibt und wir eine Rolle möchten, die allen oder fast allen Zugriff gewährt? Unsere Token-Nutzlast wäre riesig. Dies wird gelöst, indem die Ressourcen verschachtelt und nur die übergeordnete Ressource in den Gültigkeitsbereich des Zugriffstokens eingefügt werden.


Die Autorisierung ist ein kompliziertes Thema, das je nach den Anforderungen der jeweiligen Anwendung behandelt werden muss.

Miso
quelle
Danke für Ihre Antwort. Das ist sehr hilfreich. Ich habe eine Frage zu mehreren Rollen pro Benutzer. Haben Sie jemals einen Fall, in dem sich Rollenberechtigungen überschneiden? Wie Kassierer hat payment:[read], hat Verkäufer payment: [create]. Sammeln Sie in diesem Fall Berechtigungen?
Robert
Wenn Sie Rollen mit wiederholten Fähigkeiten haben (resource/action), müssen Sie diese zusammenführen. Wenn sich die Berechtigungen überschneiden, müssen Sie sie aggregieren. Die Idee besteht darin, nur die Ressourcen und Aktionen zu definieren, die im Token zulässig sind, und die Rollen als Abstraktion zu belassen, die den Kunden eine weniger komplizierte Möglichkeit zum Umgang mit Berechtigungen bietet.
Miso
1
Was ist, wenn ein Benutzer nur die Möglichkeit hat, auf Ressourcen zu reagieren, die er besitzt? Wie ein Bankkonto zum Beispiel bestimmt "bank_account": ["read", "update"] das nicht. Wo genau findet der Autorisierungsprozess in einem Microservices-System statt? Auf einem zentralen Autorisierungsserver oder jeder Dienst seine eigene Autorisierung?
rocketspacer
@rocketspacer. Deshalb hat der Token die userEigenschaft in seiner Nutzlast. Die Art und Weise, wie ich eine Ressource sperre, die einem Benutzer gehört, besteht darin, den userAnspruch der URL zuzuordnen. Zum Beispiel: /users/coyote/back-accountwäre nur mit einem Token mit userAnspruch gleich zugänglich coyote. Ich hoffe das hilft.
Miso
3

Ich denke, egal was passiert, Sie möchten, dass Ihre Dienste ein Authentifizierungstoken akzeptieren, das von einem Authentifizierungsdienst bereitgestellt wird, den Sie schreiben, um Benutzer zu validieren. Dies ist der einfachste und sicherste Weg, um einen Missbrauch Ihrer Microservices zu verhindern. Wenn Sie möchten, dass ein Kunde eine gute Erfahrung macht, sollten Sie die kritischen Funktionen im Allgemeinen selbst implementieren und gründlich testen, um sicherzustellen, dass die von Ihnen angebotenen Funktionen gut implementiert sind.

Da alle Anrufer Ihre Microservices nachweisen müssen, dass sie authentifiziert wurden, können Sie auch Berechtigungen an diese Authentifizierung binden. Wenn Sie die Möglichkeit bieten, einen Benutzer an eine beliebige Zugriffsgruppe zu binden (oder Gruppen, wenn Sie Lust haben, Berechtigungen hinzuzufügen oder zu subtrahieren, ist hier schwieriger), werden von Ihren Kunden weniger Fragen dazu gestellt, warum der Benutzer berechtigt ist x konnte eine unerwünschte Operation ausführen. In jedem Fall muss jemand die Zugriffsliste für jeden Dienst überprüfen, also können Sie es auch sein. Es ist etwas, das am Anfang aller Dienste sehr leicht codiert werden würde (if ( !TokenAuthorized(this.ServiceName, this.token) { Raise error }) Dass Sie es genauso gut tun und die Benutzergruppen selbst im Auge behalten können. Es ist richtig, dass Sie über einen Berechtigungsgruppen-Manager verfügen und ihn in die Benutzerverwaltungs-Benutzeroberfläche einbinden müssen (vorhandene verwenden / neue Gruppe für Benutzerberechtigungen erstellen). Listen Sie beim Bearbeiten der Definition unbedingt die Benutzer auf, die an eine Gruppe gebunden sind, um Verwirrung zu vermeiden . Aber es ist kein harter Job. Halten Sie einfach Metadaten für alle Services bereit und verknüpfen Sie das Nachschlagen der Zuordnung zwischen Gruppe und Service mit der Authentifizierungstoken-Verarbeitung.

Okay, es gibt einige Details, aber jeder Ihrer Clients, der diese Funktionalität wünscht, müsste dies auf jeden Fall codieren. Wenn Sie die dreistufigen Benutzerberechtigungen unterstützen, können Sie sie auch einfach so erweitern, dass sie pro Benutzerzugriff verfügbar sind Gruppen. Wahrscheinlich ist eine logische Schnittstelle zwischen Basisgruppenberechtigungen und benutzerspezifischen Berechtigungen die richtige Zusammenfassung. Wenn Sie jedoch Basisberechtigungen für Administrator-, Agenten- und Endbenutzerbasisberechtigungen hinzufügen und entfernen möchten, müssen Sie dies tun Das Tristate-Flag für die Verwendung in den Berechtigungsgruppen: "Berechtigung hinzufügen", "Berechtigung verweigern", "Standardberechtigung" und "Berechtigungen entsprechend kombinieren".

(Hinweis: Dies sollte alles über SSL oder sogar über bidirektionales SSL geschehen, wenn Sie sich Sorgen über die Sicherheit beider Gesprächsenden machen. Wenn Sie diese Token an einen Angreifer "lecken", ist er in der Situation, als ob er d hat ein Passwort geknackt.)

BenPen
quelle
Während ich über Infrastruktur und Implementierung nachdachte, vergaß ich das Kundenerlebnis völlig. Ich mag die Idee, Regeln zu erstellen, die mehr zu unserem Geschäft passen. Administratoren, Agenten und Endbenutzer sind zu allgemein und wir planen, mehr Benutzertypen zu implementieren, die aussagekräftiger und mit unserer geschäftlichen und allgegenwärtigen Sprache verknüpft sind.
Robert
Ich war nicht in der Lage , das zu korrigieren „anded“ Tippfehler im letzten Satz , weil ich es nicht herausfinden konnte.
Tulains Córdova
Es ist nicht unbedingt ein Tippfehler, aber ich werde es klarer machen ..
BenPen
1

Meiner Ansicht nach haben Sie hier zwei Möglichkeiten.

  • Wenn Sie nur konfigurierbaren Zugriff auf im Wesentlichen dieselbe Anwendung benötigen, lassen Sie die Dienste die Berechtigungen überprüfen und geben Sie Ihren Kunden eine Schnittstelle, über die sie die Berechtigungen für jede Rolle ändern können. Auf diese Weise können die meisten Benutzer die Standardrollenkonfiguration verwenden, mit der die Kunden die Rollen optimieren oder neue Rollen erstellen können, die ihren Anforderungen entsprechen.

  • Wenn Ihre Kunden ihre eigenen Anwendungen entwickeln, sollten sie ihre eigenen Zwischen-APIs einführen. Dieser stellt eine Verbindung zu Ihrem Administrator her, überprüft die eingehende Anforderung jedoch anhand der eigenen benutzerdefinierten Authentifizierungsanforderungen, bevor er Ihre Dienste aufruft

Ewan
quelle
1

Sicherheitsüberlegung

Wenn ich Ihr Design gut verstehe, beabsichtigen Sie, einige Mechanismen zur Ressourcenzugriffskontrolle an den Client zu delegieren, dh eine aufwendige App reduziert die Elemente, die ein Benutzer sehen kann. Ihre Annahme ist:

Mikrodienste und ihr Autorisierungssystem sollten sich nicht um die Bedürfnisse der Kunden kümmern, da sie nur Verbraucher sind und nicht Teil des Systems

Ich sehe hier zwei ernsthafte Probleme für ernsthafte Geschäfte:

  • Was passiert, wenn ein anderer betrügerischer Benutzer (z. B. in einem Werk Ihres Partners) die Client-App zurückentwickelt und sich über die API informiert, die Einschränkungen umgeht, die sein Unternehmen dem Client auferlegt hat, und diese Informationen verwendet, um Ihrem Unternehmen Schaden zuzufügen? Ihr Unternehmen wird Schadensersatz verlangen, aber das Partnerunternehmen wird argumentieren, dass Sie nicht die Mittel angegeben haben, um Ihre Daten ausreichend gut zu schützen.
  • Normalerweise ist es nur eine Frage der Zeit, ob sensible Daten missbraucht werden (oder die Prüfung das Risiko entdeckt), und Ihr Management wird am Ende eine genauere Kontrolle dieser Daten fordern.

Aus diesem Grund empfehle ich, solche Ereignisse zu antizipieren und Autorisierungsanfragen zu bearbeiten. Sie befinden sich in einer frühen Phase des Reengineerings und es wird viel einfacher sein, diese in Ihrer Architektur zu berücksichtigen (auch wenn Sie nicht alle implementieren) als später.

Wenn Sie Ihre derzeitige Position weiter verfolgen, wenden Sie sich mindestens an Ihren Informationssicherheitsbeauftragten.

Wie setzt man das um?

Sie haben den Trick:

Auf diese Weise müssten wir nur Token-Bereiche verfolgen.

Ok, Sie beabsichtigen, einige allgemeine Token zu verwenden, die vom Client ausgewählt wurden. Wieder eine Schwäche in meinem Auge, weil einige Kunden außerhalb Ihrer Kontrolle sein können.

Ich weiß nicht, ob Sie JWT bereits verwenden oder ob Sie andere Techniken anwenden. Wenn Sie jedoch JWT verwenden, verfügen Sie möglicherweise über ein Identitätstoken, das die Identität des Benutzers enthält (und sogar über ein zweites Token, mit dem die Ursprungs-App sicher identifiziert wird, sodass Sie das Vertrauensniveau zwischen Inhouse-Clients und externen Clients unterscheiden können ).

Wenn Sie sich für eine Microservice-Architektur entscheiden, möchte ich vorschlagen, den Unterschied zwischen dem Benutzerverwaltungs- und Authentifizierungsprozess (der als dedizierter Dienst ausgeführt werden sollte) und der Zugriffskontrolle (die für jeden Microservice spezifisch ist und sollte) zu verdeutlichen von jedem von ihnen vor Ort gehandhabt werden). Natürlich sollte ein Admin-Client einen umfassenden Überblick über mehrere Dienste geben, um die Verwendung zu vereinfachen.

Christophe
quelle
1
Sehr guter Rat hier. Ich mag die Idee mit dem zweiten Token.
Robert
1

Hier gibt es auch eine kurze Antwort. Sie sollten alle Kernfunktionen, die Sie Ihren "Kunden" anbieten möchten, selbst implementieren . Es scheint problematisch zu sein, dass Clients ein so grundlegendes Verhalten wie Benutzerberechtigungen selbst hinzufügen, da Sie bereits eine Benutzerauthentifizierung durchführen. Wenn Sie es dem Client überlassen, es zu implementieren, werden möglicherweise mehrere Implementierungen desselben Berechtigungscodes "unterstützt". Auch wenn Sie es nicht "besitzen", wird es Fehler im Code geben, und Sie möchten, dass Ihre Clients die Funktionalität haben, die sie erwartet hatten, und dass Sie die Lösung der Probleme unterstützen, die ein Client hat. Es macht keinen Spaß, mehrere Codebasen zu unterstützen.

BenPen
quelle