Zurück zu Microservices mit Istio. Teil 3



Hinweis perev. : Der erste Teil dieser Reihe war der Einführung und Demonstration von Istio-Funktionen gewidmet, der zweite dem fein abgestimmten Routing und dem Netzwerkverkehrsmanagement. Jetzt werden wir über Sicherheit sprechen: Um die damit verbundenen Grundfunktionen zu demonstrieren, verwendet der Autor den Auth0-Identitätsdienst, aber andere Anbieter können analog dazu konfiguriert werden.

Wir haben einen Kubernetes-Cluster eingerichtet, in dem Istio und die Mikroservice-Anwendung Sentiment Analysis bereitgestellt wurden. So wurde Istio demonstriert.

Mit Istio konnten wir die Services klein halten, da sie keine „Ebenen“ wie Wiederholungsversuche, Retouts, Timeouts, Leistungsschalter, Ablaufverfolgung und Überwachung implementieren müssen . Darüber hinaus verwendeten wir fortschrittliche Test- und Bereitstellungstechniken: A / B-Tests, Spiegelung und kanarische Rollouts.



In dem neuen Material werden wir uns mit den letzten Schichten auf dem Weg zum Geschäftswert befassen: Authentifizierung und Autorisierung - und in Istio ist dies eine echte Freude!

Authentifizierung und Autorisierung in Istio


Ich hätte nie geglaubt, dass ich mich von Authentifizierung und Autorisierung inspirieren lassen würde. Was kann Istio technologisch bieten, um diese Themen spannend zu machen und Sie noch mehr zu inspirieren?

Die Antwort ist einfach: Istio überträgt die Verantwortung für diese Funktionen von Ihren Diensten auf Envoy-Proxys. Wenn die Anforderungen die Dienste erreichen, sind sie bereits authentifiziert und autorisiert, sodass Sie nur noch Code schreiben müssen, der für Unternehmen nützlich ist.

Hört sich gut an? Schauen wir mal rein!

Authentifizierung mit Auth0


Wir werden Auth0 als Server für die Identitäts- und Zugriffsverwaltung verwenden. Es gibt eine Testversion, die intuitiv zu bedienen ist und die mir einfach gefällt. Dieselben Prinzipien können jedoch auf jede andere OpenID Connect-Implementierung angewendet werden: KeyCloak, IdentityServer und viele andere.

Gehen Sie zunächst mit Ihrem Konto zum Auth0-Portal , erstellen Sie einen Mandanten ( Mandant - " Mandant ", logische Isolationseinheit, weitere Details finden Sie in der Dokumentation - ca. Übertragung) und gehen Sie zu Anwendungen> Standard-App und wählen Sie Domäne , wie im folgenden Screenshot gezeigt ::



Geben Sie diese Domäne in der resource-manifests/istio/security/auth-policy.yaml ( Quelle ) an:

 apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata: name: auth-policy spec: targets: - name: sa-web-app - name: sa-feedback origins: - jwt: issuer: "https://{YOUR_DOMAIN}/" jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json" principalBinding: USE_ORIGIN 

Mit einer solchen Ressource konfiguriert Pilot (eine der drei Grundkomponenten von Control Plane in Istio - ca. Transl.) Envoys so , dass Anforderungen authentifiziert werden, bevor sie an Dienste weitergeleitet werden: sa-web-app und sa-feedback . Gleichzeitig gilt die Konfiguration nicht für die Gesandten des sa-frontend , sodass wir das Frontend nicht authentifiziert lassen können. Führen Sie den folgenden Befehl aus, um eine Richtlinie anzuwenden:

 $ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml policy.authentication.istio.io “auth-policy” created 

Kehren Sie zur Seite zurück und stellen Sie eine Anfrage - Sie werden sehen, dass sie im Status 401 Nicht autorisiert endet. Jetzt leiten wir Front-End-Benutzer zur Authentifizierung mit Auth0 um.

Authentifizierung mit Auth0 anfordern


Um Endbenutzeranforderungen zu authentifizieren, müssen Sie in Auth0 eine API erstellen, die authentifizierte Dienste (Bewertungen, Details und Bewertungen) darstellt. Um eine API zu erstellen, gehen Sie zu Auth0 Portal> APIs> API erstellen und füllen Sie das folgende Formular aus:



Die wichtige Information hier ist Identifier , den wir später im Skript verwenden werden. Schreiben wir es uns so aus:

  • Zielgruppe : {YOUR_AUDIENCE}

Die verbleibenden Details finden Sie im Auth0-Portal im Abschnitt Anwendungen - wählen Sie Testanwendung (sie wird automatisch mit der API erstellt).

Hier schreiben wir:

  • Domain : {YOUR_DOMAIN}
  • Kunden- ID: {YOUR_CLIENT_ID}

Scrollen Sie in der Testanwendung zum Textfeld Zulässige Rückruf- URLs (die zulässigen URLs für den Rückruf), in dem wir die URL angeben, an die der Anruf nach Abschluss der Authentifizierung gesendet werden soll. In unserem Fall ist es:

 http://{EXTERNAL_IP}/callback 

Fügen Sie für zulässige Abmelde-URLs (zulässige URLs zum Abmelden) Folgendes hinzu:

 http://{EXTERNAL_IP}/logout 

Gehen wir weiter zum Frontend.

Frontend-Update


auth0 Zweig auth0 des Repositorys [istio-mastery] . In diesem Thread wird der Front-End-Code geändert, um Benutzer zur Authentifizierung an Auth0 umzuleiten und das JWT-Token in Anforderungen für andere Dienste zu verwenden. Letzteres wird wie folgt implementiert ( App.js ):

 analyzeSentence() { fetch('/sentiment', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token }, body: JSON.stringify({ sentence: this.textField.getValue() }) }) .then(response => response.json()) .then(data => this.setState(data)); } 

Um das Frontend in die Verwendung von Mandantendaten in Auth0 zu konvertieren, öffnen Sie sa-frontend/src/services/Auth.js und ersetzen Sie die oben geschriebenen Werte ( Auth.js ):

 const Config = { clientID: '{YOUR_CLIENT_ID}', domain:'{YOUR_DOMAIN}', audience: '{YOUR_AUDIENCE}', ingressIP: '{EXTERNAL_IP}' //      } 

Die Anwendung ist fertig. Geben Sie Ihre Docker-ID in den folgenden Befehlen an, wenn Sie die vorgenommenen Änderungen erstellen und bereitstellen:

 $ docker build -f sa-frontend/Dockerfile \ -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 \ sa-frontend $ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 $ kubectl set image deployment/sa-frontend \ sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 

Probieren Sie die App! Sie werden zu Auth0 weitergeleitet, wo Sie sich anmelden (oder registrieren) müssen. Anschließend werden Sie zu der Seite zurückgeschickt, von der aus bereits authentifizierte Anforderungen gestellt werden. Wenn Sie die in den ersten Teilen des Artikels genannten Curl-Befehle ausprobieren, erhalten Sie einen 401-Statuscode , der angibt, dass die Anforderung nicht autorisiert ist.

Machen wir den nächsten Schritt - autorisieren Sie Anfragen.

Autorisierung mit Auth0


Durch die Authentifizierung können wir verstehen, wer der Benutzer ist. Um jedoch herauszufinden, auf was er Zugriff hat, ist eine Autorisierung erforderlich. Istio bietet auch hierfür Tools an.

Als Beispiel erstellen wir zwei Benutzergruppen (siehe Abbildung unten):

  • Benutzer (Benutzer) - nur mit Zugriff auf die Dienste SA-WebApp und SA-Frontend;
  • Moderatoren - mit Zugriff auf alle drei Dienste.


Berechtigungskonzept

Um diese Gruppen zu erstellen, verwenden wir die Auth0-Autorisierungserweiterung und verwenden Istio, um ihnen verschiedene Zugriffsebenen bereitzustellen.

Installation und Konfiguration der Auth0-Autorisierung


Gehen Sie im Auth0-Portal zu Erweiterungen und installieren Sie die Auth0-Autorisierung . Gehen Sie nach der Installation zur Autorisierungserweiterung und dort zur Konfiguration des Mandanten, indem Sie oben rechts klicken und die entsprechende Menüoption (Konfiguration) auswählen. Aktivieren Sie Gruppen und klicken Sie auf die Schaltfläche Regel veröffentlichen .



Gruppenerstellung


Gehen Sie in der Autorisierungserweiterung zu Gruppen und erstellen Sie eine Moderatorengruppe . Da wir alle authentifizierten Benutzer als normal betrachten, ist es nicht erforderlich, eine zusätzliche Gruppe für sie zu erstellen.

Wählen Sie die Gruppe Moderatoren aus, klicken Sie auf Mitglieder hinzufügen und fügen Sie Ihr Hauptkonto hinzu. Lassen Sie einige Benutzer ohne Gruppe, um sicherzustellen, dass ihnen der Zugriff verweigert wird. (Neue Benutzer können manuell über Auth0 Portal> Benutzer> Benutzer erstellen erstellt werden .)

Gruppenanspruch zum Zugriffstoken hinzufügen


Benutzer werden zu Gruppen hinzugefügt, diese Informationen sollten jedoch in Zugriffstoken wiedergegeben werden. Um OpenID Connect zu erfüllen und gleichzeitig die benötigten Gruppen zurückzugeben, muss das Token seinen benutzerdefinierten Anspruch hinzufügen. Es wird durch die Regeln von Auth0 implementiert.

Um eine Regel zu erstellen, rufen Sie das Auth0-Portal zu Regeln auf , klicken Sie auf Regel erstellen und wählen Sie eine leere Regel aus den Vorlagen aus.



Kopieren Sie den folgenden Code und speichern Sie ihn als neue Regel zum Hinzufügen von Gruppenansprüchen ( namespacedGroup.js ):

 function (user, context, callback) { context.accessToken['https://sa.io/group'] = user.groups[0]; return callback(null, user, context); } 

Hinweis : Dieser Code verwendet die erste in der Autorisierungserweiterung definierte Benutzergruppe und fügt sie dem Zugriffstoken als benutzerdefinierten Anspruch hinzu (unter seinem Namespace, wie von Auth0 gefordert).

Kehren Sie zur Seite Regeln zurück und vergewissern Sie sich, dass zwei Regeln in der folgenden Reihenfolge geschrieben wurden:

  • auth0-authorisation-extension
  • Gruppenanspruch hinzufügen

Die Reihenfolge ist wichtig, da das Gruppenfeld asynchron die Auth0-Authorization-Extension- Regel empfängt und dann von der zweiten Regel als Anspruch hinzugefügt wird. Das Ergebnis ist ein solches Zugriffstoken:

 { "https://sa.io/group": "Moderators", "iss": "https://sentiment-analysis.eu.auth0.com/", "sub": "google-oauth2|196405271625531691872" // [  ] } 

Jetzt müssen Sie den Envoy-Proxy konfigurieren, um den Benutzerzugriff zu überprüfen, für den die Gruppe aus dem Anspruch ( https://sa.io/group ) im zurückgegebenen Zugriffstoken abgerufen wird. Dies ist das Thema für den nächsten Abschnitt des Artikels.

Istio-Berechtigungskonfiguration


Damit die Autorisierung funktioniert, müssen Sie RBAC für Istio aktivieren. Verwenden Sie dazu die folgende Konfiguration:

 apiVersion: "rbac.istio.io/v1alpha1" kind: RbacConfig metadata: name: default spec: mode: 'ON_WITH_INCLUSION' # 1 inclusion: services: # 2 - "sa-frontend.default.svc.cluster.local" - "sa-web-app.default.svc.cluster.local" - "sa-feedback.default.svc.cluster.local" 

Erklärungen:
  • 1 - RBAC nur für Dienste und Namespaces aktivieren, die im Feld Inclusion sind;
  • 2 - Listen Sie die Liste unserer Dienstleistungen auf.


Wir wenden die Konfiguration mit diesem Befehl an:

 $ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml rbacconfig.rbac.istio.io/default created 

Jetzt erfordern alle Dienste eine rollenbasierte Zugriffskontrolle. Mit anderen Worten, der Zugriff auf alle Dienste wird verweigert und führt zu einer RBAC: access denied Antwort RBAC: access denied . Erlauben Sie nun autorisierten Benutzern den Zugriff.

Zugriffskonfiguration für reguläre Benutzer


Alle Benutzer müssen Zugriff auf die Dienste SA-Frontend und SA-WebApp haben. Implementiert mit den folgenden Istio-Ressourcen:

  • ServiceRole - definiert die Rechte, die der Benutzer hat;
  • ServiceRoleBinding - Bestimmt, wem diese ServiceRole gehört.

Erlauben Sie normalen Benutzern den Zugriff auf bestimmte Dienste ( servicerole.yaml ):

 apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRole metadata: name: regular-user namespace: default spec: rules: - services: - "sa-frontend.default.svc.cluster.local" - "sa-web-app.default.svc.cluster.local" paths: ["*"] methods: ["*"] 

Wenden Sie durch regular-user-binding eine ServiceRole auf alle Besucher der Seite an ( reguläre Benutzerservice-Rollenbindung.yaml ):

 apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRoleBinding metadata: name: regular-user-binding namespace: default spec: subjects: - user: "*" roleRef: kind: ServiceRole name: "regular-user" 

Bedeutet "alle Benutzer", dass nicht authentifizierte Benutzer Zugriff auf SA WebApp erhalten? Nein, die Richtlinie überprüft die Gültigkeit des JWT-Tokens.

Konfiguration anwenden:

 $ kubectl apply -f resource-manifests/istio/security/user-role.yaml servicerole.rbac.istio.io/regular-user created servicerolebinding.rbac.istio.io/regular-user-binding created 

Zugriffskonfiguration für Moderatoren


Für Moderatoren möchten wir den Zugriff auf alle Dienste ermöglichen ( mod-service-role.yaml ):

 apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRole metadata: name: mod-user namespace: default spec: rules: - services: ["*"] paths: ["*"] methods: ["*"] 

Wir möchten solche Rechte jedoch nur für Benutzer, deren Zugriffstoken den Anspruch https://sa.io/group mit dem Wert Moderators ( mod-service-role-binding.yaml ) hat:

 apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRoleBinding metadata: name: mod-user-binding namespace: default spec: subjects: - properties: request.auth.claims[https://sa.io/group]: "Moderators" roleRef: kind: ServiceRole name: "mod-user" 

Konfiguration anwenden:

 $ kubectl apply -f resource-manifests/istio/security/mod-role.yaml servicerole.rbac.istio.io/mod-user created servicerolebinding.rbac.istio.io/mod-user-binding created 

Aufgrund des Zwischenspeicherns in Gesandten kann es einige Minuten dauern, bis die Autorisierungsregeln wirksam werden. Danach können Sie sicherstellen, dass Benutzer und Moderatoren unterschiedliche Zugriffsebenen haben.

Fazit zu diesem Teil


Im Ernst: Haben Sie jemals einen einfacheren, mühelosen, skalierbaren und sicheren Ansatz für die Authentifizierung und Autorisierung gesehen?

Es waren nur drei Istio-Ressourcen (RbacConfig, ServiceRole und ServiceRoleBinding) erforderlich, um eine genaue Kontrolle über die Authentifizierung und Autorisierung des Endbenutzerzugriffs auf Dienste zu erreichen.

Darüber hinaus haben wir uns im Rahmen unserer Gesandtsdienste um diese Probleme gekümmert und Folgendes erreicht:

  • Reduzieren der Menge an Beispielcode, die Sicherheitsprobleme und Fehler enthalten kann;
  • Reduzierung der Anzahl dummer Situationen, in denen ein Endpunkt von außen zugänglich war und vergessen hat, ihn zu melden;
  • Sie müssen nicht mehr alle Dienste aktualisieren, wenn eine neue Rolle oder ein neues Recht hinzugefügt wird.
  • dass die neuen Dienste einfach, sicher und schnell bleiben.

Fazit


Mit Istio können Teams ihre Ressourcen auf geschäftskritische Aufgaben konzentrieren, ohne den Aufwand für die Services zu erhöhen, und sie wieder in den Mikrostatus versetzen.

Der Artikel (in drei Teilen) enthielt Grundkenntnisse und vorgefertigte praktische Anweisungen für den Beginn der Arbeit mit Istio in realen Projekten.

PS vom Übersetzer


Lesen Sie auch in unserem Blog:

Source: https://habr.com/ru/post/de443668/


All Articles