Povratak na mikroservise s Istiom. 3. dio

Povratak na mikroservise s Istiom. 3. dio

Bilješka. prev.: Prvi dio ova serija bila je posvećena upoznavanju mogućnosti Istioa i njihovom demonstriranju na djelu, drugi — fino podešeno usmjeravanje i upravljanje mrežnim prometom. Sada ćemo govoriti o sigurnosti: za demonstraciju osnovnih funkcija koje se odnose na nju, autor koristi uslugu identiteta Auth0, ali drugi pružatelji mogu biti konfigurirani na sličan način.

Postavili smo Kubernetes klaster u kojem smo implementirali Istio i primjer mikroservisne aplikacije, Sentiment Analysis, kako bismo demonstrirali Istiove mogućnosti.

Uz Istio, uspjeli smo zadržati naše usluge malim jer ne trebaju implementirati slojeve kao što su ponovni pokušaji, istek vremena, prekidači, praćenje, nadgledanje. Uz to, upotrijebili smo napredne tehnike testiranja i implementacije: A/B testiranje, zrcaljenje i kanarsko uvođenje.

Povratak na mikroservise s Istiom. 3. dio

U novom materijalu bavit ćemo se završnim slojevima na putu do poslovne vrijednosti: autentifikacijom i autorizacijom – a u Istiu je to pravi užitak!

Autentifikacija i autorizacija u Istio

Nikada ne bih vjerovao da će me inspirirati autentifikacija i autorizacija. Što Istio može ponuditi iz tehnološke perspektive da vam ove teme budu zabavne i, još više, inspirativne?

Odgovor je jednostavan: Istio prebacuje odgovornost za ove mogućnosti s vaših usluga na Envoy proxy. Dok zahtjevi stignu do servisa, oni su već autentificirani i autorizirani, tako da sve što trebate učiniti je napisati poslovno koristan kod.

Zvuči dobro? Pogledajmo unutra!

Autentifikacija s Auth0

Kao poslužitelj za upravljanje identitetom i pristupom koristit ćemo Auth0 koji ima probnu verziju, intuitivan je za korištenje i jednostavno mi se sviđa. Međutim, isti principi mogu se primijeniti na bilo koji drugi Implementacije OpenID Connecta: KeyCloak, IdentityServer i mnogi drugi.

Za početak idite na Portal Auth0 sa svojim računom stvorite stanara (stanar - “stanar”, logična jedinica izolacije, za više detalja vidi dokumentacija - cca. prev.) i idi na Aplikacije > Zadana aplikacijaodabirući Domena, kao što je prikazano na snimci zaslona u nastavku:

Povratak na mikroservise s Istiom. 3. dio

Navedite ovu domenu u datoteci resource-manifests/istio/security/auth-policy.yaml (izvor):

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

S takvim resursom, Pilote (jedna od tri osnovne komponente kontrolne ravnine u Istio - pribl. prijevod) konfigurira Envoy za provjeru autentičnosti zahtjeva prije nego što ih proslijedi uslugama: sa-web-app и sa-feedback. Istodobno, konfiguracija se ne primjenjuje na uslugu Envoys sa-frontend, što nam omogućuje da ostavimo sučelje neovjereno. Za primjenu Pravila pokrenite naredbu:

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

Vratite se na stranicu i napravite zahtjev - vidjet ćete da završava statusom 401 neovlašteno. Sada preusmjerimo sučelje korisnike na autentifikaciju s Auth0.

Autentifikacija zahtjeva s Auth0

Za provjeru vjerodostojnosti zahtjeva krajnjih korisnika, morate stvoriti API u Auth0 koji će predstavljati provjerene usluge (recenzije, detalji i ocjene). Za izradu API-ja idite na Auth0 Portal > API-ji > Stvori API i ispuni obrazac:

Povratak na mikroservise s Istiom. 3. dio

Ovdje je važna informacija identificirati, koji ćemo kasnije koristiti u skripti. Zapišimo to ovako:

  • publika: {VAŠA_PUBLIKA}

Preostale pojedinosti koje trebamo nalaze se na portalu Auth0 u odjeljku Aplikacije - Odaberi Testna aplikacija (stvara se automatski zajedno s API-jem).

Ovdje ćemo napisati:

  • Domena: {VAŠA_DOMAIN}
  • Id klijenta: {YOUR_CLIENT_ID}

Pomaknite se na Testna aplikacija u tekstualno polje Dopušteni URL-ovi za povratni poziv (razriješeni URL-ovi za povratni poziv), u kojem navodimo URL na koji bi poziv trebao biti poslan nakon dovršetka autentifikacije. U našem slučaju to je:

http://{EXTERNAL_IP}/callback

I za Dopušteni URL-ovi za odjavu (dopušteni URL-ovi za odjavu) dodaj:

http://{EXTERNAL_IP}/logout

Prijeđimo na sučelje.

Ažuriranje sučelja

Prijeđi na poslovnicu auth0 spremište [istio-mastery]. U ovoj se grani kod sučelja mijenja kako bi preusmjerio korisnike na Auth0 za provjeru autentičnosti i koristio JWT token u zahtjevima drugim uslugama. Potonji se implementira na sljedeći način (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));
}

Da biste promijenili sučelje za korištenje podataka stanara u Auth0, otvorite sa-frontend/src/services/Auth.js i zamijenite u njemu vrijednosti koje smo napisali gore (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}

Aplikacija je spremna. Navedite svoj Docker ID u naredbama u nastavku prilikom izgradnje i implementacije učinjenih promjena:

$ 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

Isprobajte aplikaciju! Bit ćete preusmjereni na Auth0, gdje se trebate prijaviti (ili registrirati), nakon čega ćete biti vraćeni na stranicu s koje će se slati već autentificirani zahtjevi. Ako isprobate naredbe spomenute u prvim dijelovima članka s curlom, dobit ćete kod 401 statusni kod, signalizirajući da zahtjev nije autoriziran.

Poduzmimo sljedeći korak - autorizirajmo zahtjeve.

Autorizacija s Auth0

Autentifikacija nam omogućuje da shvatimo tko je korisnik, ali autorizacija je potrebna da bismo znali čemu imaju pristup. Istio također nudi alate za to.

Kao primjer, stvorimo dvije korisničke grupe (pogledajte dijagram u nastavku):

  • Članovi (korisnici) — s pristupom samo uslugama SA-WebApp i SA-Frontend;
  • moderatori (moderatori) — s pristupom sve tri usluge.

Povratak na mikroservise s Istiom. 3. dio
Koncept autorizacije

Za stvaranje ovih grupa koristit ćemo proširenje Auth0 Authorization i koristiti Istio kako bismo im pružili različite razine pristupa.

Instalacija i konfiguracija Auth0 Autorizacije

Na portalu Auth0 idite na proširenja (Proširenja) i instalirajte Auth0 Autorizacija. Nakon instalacije idite na Proširenje ovlaštenja, a tamo - na konfiguraciju zakupca klikom gore desno i odabirom odgovarajuće opcije izbornika (Konfiguracija). Aktivirajte grupe (skupine) i kliknite gumb za objavljivanje pravila (Pravilo objave).

Povratak na mikroservise s Istiom. 3. dio

Stvorite grupe

U Proširenje autorizacije idite na Klanovi i stvorite grupu Moderatori. Budući da ćemo sve autentificirane korisnike tretirati kao obične korisnike, nema potrebe stvarati dodatnu grupu za njih.

Odaberite grupu Moderatori, Pritisnite Dodaj članove, dodajte svoj glavni račun. Ostavite neke korisnike bez grupe kako biste bili sigurni da im je pristup zabranjen. (Novi korisnici mogu se kreirati ručno putem Auth0 Portal > Korisnici > Stvori korisnika.)

Dodaj grupni zahtjev za pristupni token

Korisnici su dodani u grupe, ali ove informacije također moraju biti prikazane u pristupnim tokenima. Kako bismo bili u skladu s OpenID Connectom i istovremeno vratili grupe koje su nam potrebne, token će morati dodati vlastiti prilagođena tvrdnja. Implementirano kroz Auth0 pravila.

Da biste stvorili pravilo, idite na Auth0 Portal do Pravila, Pritisnite Stvori pravilo i odaberite prazno pravilo iz predložaka.

Povratak na mikroservise s Istiom. 3. dio

Kopirajte donji kod i spremite ga kao novo pravilo Dodaj grupni zahtjev (namespacedGroup.js):

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

Primijetiti: Ovaj kod uzima prvu korisničku grupu definiranu u proširenju autorizacije i dodaje je pristupnom tokenu kao prilagođeni zahtjev (pod njezinim prostorom imena, kako zahtijeva Auth0).

Povratak na stranicu Pravila i provjerite imate li dva pravila napisana sljedećim redoslijedom:

  • auth0-autorizacija-proširenje
  • Dodaj grupni zahtjev

Redoslijed je važan jer grupno polje prima pravilo asinkrono auth0-autorizacija-proširenje a nakon toga se dodaje kao tvrdnja drugim pravilom. Rezultat je pristupni token poput ovog:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [сокращено для наглядности]
}

Sada trebate konfigurirati Envoy proxy za provjeru pristupa korisnika, za što će grupa biti povučena iz zahtjeva (https://sa.io/group) u vraćenom pristupnom tokenu. Ovo je tema za sljedeći dio članka.

Konfiguracija autorizacije u Istiu

Da bi autorizacija radila, morate omogućiti RBAC za Istio. Da bismo to učinili, koristit ćemo sljedeću konfiguraciju:

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" 

Objašnjenje:

  • 1 — omogućite RBAC samo za usluge i prostore imena navedene u polju Inclusion;
  • 2 — navodimo popis naših usluga.

Primijenimo konfiguraciju sljedećom naredbom:

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

Sve usluge sada zahtijevaju kontrolu pristupa temeljenu na ulogama. Drugim riječima, pristup svim uslugama je zabranjen i rezultirat će odgovorom RBAC: access denied. Sada dopustimo pristup ovlaštenim korisnicima.

Konfiguracija pristupa za obične korisnike

Svi korisnici moraju imati pristup uslugama SA-Frontend i SA-WebApp. Implementirano pomoću sljedećih Istio resursa:

  • ServiceRole — utvrđuje prava koja korisnik ima;
  • ServiceRoleBinding — određuje kome pripada ova ServiceRole.

Za obične korisnike omogućit ćemo pristup određenim uslugama (servisna uloga.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: ["*"]

I kroz regular-user-binding primijenite ServiceRole na sve posjetitelje stranice (regular-user-service-role-binding.yaml):

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

Znači li "svi korisnici" da će neautorizirani korisnici također imati pristup SA WebApp-u? Ne, pravilo će provjeriti valjanost JWT tokena.

Primijenimo konfiguracije:

$ 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

Konfiguracija pristupa za moderatore

Moderatorima želimo omogućiti pristup svim uslugama (mod-service-role.yaml):

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

Ali želimo takva prava samo za one korisnike čiji pristupni token sadrži zahtjev https://sa.io/group s vrijednošću Moderators (mod-service-role-binding.yaml):

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" 

Primijenimo konfiguracije:

$ 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

Zbog predmemoriranja u izaslanicima, može proći nekoliko minuta prije nego što pravila autorizacije stupe na snagu. Tada možete osigurati da korisnici i moderatori imaju različite razine pristupa.

Zaključak o ovom dijelu

Ali ozbiljno, jeste li ikada vidjeli jednostavniji, lakši, skalabilni i sigurniji pristup autentifikaciji i autorizaciji?

Samo su tri Istio resursa (RbacConfig, ServiceRole i ServiceRoleBinding) bila potrebna za postizanje precizne kontrole nad autentifikacijom i autorizacijom pristupa krajnjeg korisnika uslugama.

Osim toga, pobrinuli smo se za ova pitanja izvan naše službe izaslanika, postigavši:

  • smanjenje količine generičkog koda koji može sadržavati sigurnosne probleme i greške;
  • smanjenje broja glupih situacija u kojima se ispostavilo da je jedna krajnja točka dostupna izvana i zaboravili su je prijaviti;
  • eliminiranje potrebe za ažuriranjem svih usluga svaki put kada se doda nova uloga ili pravo;
  • da nove usluge ostanu jednostavne, sigurne i brze.

Izlaz

Istio omogućuje timovima da usmjere svoje resurse na poslovne zadatke bez dodavanja dodatnih troškova uslugama, vraćajući ih u mikro status.

Članak (u tri dijela) je pružio osnovna znanja i gotove praktične upute za početak rada s Istiom u stvarnim projektima.

PS od prevoditelja

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar