
Nota del traduttore.: questo ciclo è stato dedicato alla scoperta delle capacità di Istio e alla loro dimostrazione pratica. — con una gestione raffinata del routing e del traffico di rete. Ora parleremo di sicurezza: per dimostrare le funzionalità di base a essa correlate, l'autore utilizza il servizio di identità Auth0, ma analogamente è possibile configurare anche altri fornitori.
Abbiamo configurato un cluster Kubernetes, in cui abbiamo implementato Istio e un esempio di applicazione microservizi per il Sentiment Analysis, dimostrando quindi le capacità di Istio.
Grazie a Istio siamo riusciti a mantenere i servizi leggeri, poiché non necessitano dell'implementazione di livelli come i retry, i timeout, i circuit breaker, il tracing e il monitoring. Inoltre, abbiamo utilizzato tecniche avanzate di testing e deploy: A/B testing, mirroring e rollout canarino.

Nel nuovo materiale affronteremo gli strati finali verso il valore aziendale: autenticazione e autorizzazione — e con Istio è un vero e proprio piacere!
Autenticazione e autorizzazione in Istio
Non avrei mai creduto di poter trarre ispirazione dall'autenticazione e dall'autorizzazione. Cosa può offrire Istio da un punto di vista tecnologico per rendere questi argomenti interessanti e addirittura ispiratori per voi?
La risposta è semplice: Istio sposta la responsabilità di queste funzionalità dai vostri servizi al proxy Envoy. Quando le richieste raggiungono i servizi, sono già autenticate e autorizzate, quindi vi resta solo da scrivere codice utile per il business.
Sembra interessante? Scopriamolo insieme!
Autenticazione con Auth0
Utilizzeremo Auth0 come server di gestione dell'identità e dell'accesso, che offre una prova gratuita, è intuitivo da usare e mi piace semplicemente. Tuttavia, gli stessi principi possono essere applicati a qualsiasi altra : KeyCloak, IdentityServer e molti altri.
Iniziate accedendo al con il vostro account, create un tenant (un tenant è un'unità logica di isolamento, ulteriori dettagli nel — nota di traduzione) e andate su Applications > Default App, selezionando Dominio, come mostrato nello screenshot qui sotto:

Specificate questo dominio nel file resource-manifests/istio/security/auth-policy.yaml ():
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 Con questa risorsa, Pilot (uno dei tre componenti fondamentali del Control Plane in Istio — nota del traduttore) configura Envoy per autenticare le richieste prima di reindirizzarle ai servizi: sa-web-app e sa-feedback. Allo stesso tempo, la configurazione non si applica agli Envoy dei servizi, permettendoci di mantenere il frontend non autenticato. Per applicare la policy, eseguite il comando: sa-frontend$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml policy.authentication.istio.io “auth-policy” created
Tornate alla pagina e fate una richiesta — vedrete che terminerà con uno stato. Ora reindirizziamo gli utenti del frontend verso l'autenticazione con Auth0. 401 UnauthorizedAutenticazione delle richieste con Auth0
Per autenticare le richieste dell'utente finale, è necessario creare un'API in Auth0 che rappresenterà i servizi autenticati (reviews, details e ratings). Per creare l'API, andate su
Auth0 Portal > APIs > Create API e compilate il modulo: Un'informazione importante qui è

Identifier , che utilizzeremo successivamente nello script. Anotatelo così:Audience
- : {YOUR_AUDIENCE}Le rimanenti informazioni necessarie si trovano su Auth0 Portal nella sezione
Applications — selezionate Test Application (creata automaticamente insieme all'API). Qui annoteremo:
: {YOUR_DOMAIN}
- DominioClient Id
- : {YOUR_CLIENT_ID}Scorrete fino al campo di testo
Allowed Callback URLs (creata automaticamente insieme all'API). (URL consentiti per il callback), dove specificeremo l'URL a cui deve essere invocato il callback dopo il completamento dell'autenticazione. Nel nostro caso è: http://{EXTERNAL_IP}/callback Allowed Logout URLs
(URL consentiti per il logout) aggiungiamo:E per http://{EXTERNAL_IP}/logout Passiamo al frontend.
Aggiornamento del frontendPassiamo al frontend.
auth0
Passa al ramo . In questo ramo il codice del frontend è stato modificato per reindirizzare gli utenti su Auth0 per l'autenticazione e utilizzare il token JWT nelle richieste agli altri servizi. Questo è implementato nel modo seguente ( del repository [istio-mastery]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)); }):
Per passare il frontend all'utilizzo dei dati del tenant in Auth0, aprite e sostituite in esso i valori che abbiamo annotato sopra ( sa-frontend/src/services/Auth.js e sostituite al suo interno i valori che abbiamo registrato in precedenza ():
const Config = {
clientID: '{YOUR_CLIENT_ID}',
domain:'{YOUR_DOMAIN}',
audience: '{YOUR_AUDIENCE}',
ingressIP: '{EXTERNAL_IP}' // Utilizzato per il reindirizzamento dopo l'autenticazione
}L'applicazione è pronta. Specifica il tuo Docker ID nei comandi qui sotto durante la creazione e il deploy delle modifiche apportate:
$ 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-auth0Prova l'applicazione! Verrai reindirizzato su Auth0, dove dovrai effettuare il login (o registrarti), dopo di che verrai riportato sulla pagina da cui verranno effettuate le richieste già autenticate. Se provi i comandi menzionati nelle parti iniziali dell'articolo con curl, otterrai il codice 401 Status Code, che indica che la richiesta non è autorizzata.
Facciamo il passo successivo: autorizziamo le richieste.
Autorizzazione con Auth0
L'autenticazione ci permette di capire chi è l'utente, ma per scoprire a cosa ha accesso è necessaria l'autorizzazione. Istio offre strumenti anche per questo.
Come esempio, creeremo due gruppi di utenti (vedi schema qui sotto):
- Utenti (utenti) — con accesso solo ai servizi SA-WebApp e SA-Frontend;
- Moderatori (moderatori) — con accesso a tutti e tre i servizi.

Concetto di autorizzazione
Per creare questi gruppi useremo l'estensione Auth0 Authorization e, attraverso Istio, forniremo loro diversi livelli di accesso.
Installazione e configurazione di Auth0 Authorization
Nel portale Auth0, vai alla sezione estensioni (Extensions) e installa Auth0 Authorization. Dopo l'installazione, vai a Authorization Extension, quindi fai clic sulla configurazione dell'tenant in alto a destra e seleziona l'opzione dal menu (Configuration). Attiva i gruppi (Groups) e premi il pulsante di pubblicazione della regola (Publish rule).

Creazione dei gruppi
Nell'Authorization Extension, vai a Gruppi e crea il gruppo Moderators. Poiché considereremo tutti gli utenti autenticati come normali, non è necessario creare un gruppo aggiuntivo per loro.
Seleziona il gruppo Moderators, fai clic su Add Members, aggiungi il tuo account principale. Lascia alcuni utenti senza alcun gruppo per assicurarti che l'accesso a loro sia negato. (Nuovi utenti possono essere creati manualmente tramite Auth0 Portal > Users > Create User.)
Aggiungi Group Claim al Token di Accesso
Gli utenti sono stati aggiunti ai gruppi, ma queste informazioni devono essere riflesse anche nei token di accesso. Per conformarsi a OpenID Connect e restituire i gruppi di cui abbiamo bisogno, il token avrà bisogno di aggiungere il suo . Questo è implementato attraverso le regole di Auth0.
Per creare una regola, vai al portale Auth0, alla sezione Rules, fai clic su Create Rule e seleziona una regola vuota dai modelli.

Copia il codice qui sotto e salvalo come nuova regola Add Group Claim ():
function (user, context, callback) {
context.accessToken['https://sa.io/group'] = user.groups[0];
return callback(null, user, context);
}Nota: questo codice prende il primo gruppo dell'utente, definito nell'Authorization Extension, e lo aggiunge al token di accesso come custom claim (sotto il proprio spazio dei nomi, come richiesto da Auth0).
Torna alla pagina Rules e verifica che hai due regole, scritte nel seguente ordine:
- auth0-authorization-extension
- Add Group Claim
L'ordine è importante, perché il campo del gruppo riceve in modo asincrono la regola auth0-authorization-extension e viene quindi aggiunto come claim dalla seconda regola. Il risultato è un token di accesso come questo:
{
"https://sa.io/group": "Moderators",
"iss": "https://sentiment-analysis.eu.auth0.com/",
"sub": "google-oauth2|196405271625531691872"
// [ridotto per chiarezza]
} Ora è necessario configurare il proxy Envoy per verificare l'accesso degli utenti, per il quale il gruppo sarà estratto dal claim (https://sa.io/group) nel token di accesso restituito. Questo sarà trattato nella prossima sezione dell'articolo.
Configurazione dell'autorizzazione in Istio
Affinché l'autorizzazione funzioni, è necessario abilitare RBAC per Istio. Usiamo la seguente configurazione:
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" Explanations:
- 1 — attiviamo RBAC solo per i servizi e i namespace elencati nel campo
Inclusion; - 2 — elenchiamo i nostri servizi.
Applichiamo la configurazione con il seguente comando:
$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default creato Ora tutti i servizi richiedono la gestione dell'accesso basata sui ruoli (Role-Based Access Control). In altre parole, l'accesso a tutti i servizi è vietato e porterà alla risposta RBAC: access denied. Ora consentiamo l'accesso agli utenti autorizzati.
Configurazione dell'accesso per utenti normali
Tutti gli utenti devono avere accesso ai servizi SA-Frontend e SA-WebApp. Questo è implementato tramite le seguenti risorse Istio:
- ServiceRole — definisce i diritti dell'utente;
- ServiceRoleBinding — determina a chi si riferisce questo ServiceRole.
Per gli utenti normali, consentiamo l'accesso a determinati servizi ():
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: ["*"] E attraverso regular-user-binding applicheremo il ServiceRole a tutti i visitatori della pagina ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: regular-user-binding
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "regular-user"Significa che "tutti gli utenti" implica che anche gli utenti non autenticati avranno accesso a SA WebApp? No, la policy verificherà la validità del token JWT.
Applicheremo le configurazioni:
$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding createdConfigurazione di accesso per moderatori
Per i moderatori vogliamo concedere l'accesso a tutti i servizi ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: mod-user
namespace: default
spec:
rules:
- services: ["*"]
paths: ["*"]
methods: ["*"] Ma desideriamo tali diritti solo per quegli utenti il cui token di accesso ha un claim https://sa.io/group con il valore Moderators ():
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" Applicheremo le configurazioni:
$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding createdA causa della cache negli envoy, potrebbero essere necessari alcuni minuti affinché le regole di autorizzazione abbiano effetto. Dopo ciò, potrai verificare che utenti e moderatori hanno diversi livelli di accesso.
Conclusione su questa parte
Seriamente, avete mai visto un approccio più semplice, senza sforzi, scalabile e sicuro per l'autenticazione e l'autorizzazione?
Solo tre risorse di Istio (RbacConfig, ServiceRole e ServiceRoleBinding) sono state necessarie per ottenere un controllo fine sull'autenticazione e l'autorizzazione all'accesso degli utenti finali ai servizi.
Inoltre, abbiamo spostato la responsabilità di questi problemi dagli nostri servizi agli envoy, ottenendo:
- una riduzione del codice boilerplate in cui potrebbero sorgere problemi di sicurezza e bug;
- una diminuzione delle situazioni stupide in cui un endpoint risulta accessibile dall'esterno e non lo comunica;
- l'eliminazione della necessità di aggiornare tutti i servizi ogni volta che viene aggiunto un nuovo ruolo o permesso;
- affinché i nuovi servizi rimangano semplici, sicuri e veloci.
Risultato
Istio consente ai team di concentrare le proprie risorse su compiti aziendali importanti, senza aggiungere oneri ai servizi, riportandoli allo status di "micro".
L'articolo (in tre parti) ha fornito conoscenze di base e una guida pratica pronta per iniziare a lavorare con Istio in progetti reali.
P.S. dal traduttore
Leggete anche nel nostro blog:
- «Tornare ai microservizi con Istio»: , ;
- «»;
- «».
Fonte: habr.com
