Remarque perev. : La première partie de cette série a été consacrée à la présentation des capacités d'Istio et à leur démonstration en action, la seconde à un routage finement réglé et à une gestion du trafic réseau. Nous allons maintenant parler de sécurité: pour démontrer les fonctions de base qui lui sont associées, l'auteur utilise le service d'identité Auth0, mais d'autres fournisseurs peuvent être configurés par analogie avec lui.Nous avons mis en place un cluster Kubernetes dans lequel Istio et l'application de microservice d'analyse des sentiments ont été déployés, ce qui a été la démonstration d'Istio.
En utilisant Istio, nous avons pu garder les services de petite taille, car ils n'ont pas besoin d'implémenter des «couches» telles que les tentatives, retouts, délais d'attente, disjoncteurs, traçage, surveillance . De plus, nous avons utilisé des techniques avancées de test et de déploiement: tests A / B, mise en miroir et déploiements canaries.

Dans le nouveau matériel, nous traiterons des dernières couches sur le chemin de la valeur commerciale: l'authentification et l'autorisation - et à Istio, c'est un vrai plaisir!
Authentification et autorisation à Istio
Je n'aurais jamais cru que je serais inspiré par l'authentification et l'autorisation. Quelle technologie peut offrir Istio pour rendre ces sujets passionnants et encore plus pour vous inspirer?
La réponse est simple: Istio transfère la responsabilité de ces fonctionnalités de vos services aux mandataires Envoy. Au moment où les demandes parviennent aux services, elles sont déjà authentifiées et autorisées, il vous suffit donc d'écrire du code utile pour les entreprises.
Sonne bien? Regardons à l'intérieur!
Authentification avec Auth0
Nous utiliserons Auth0 comme serveur pour la gestion des identités et des accès, qui a une version d'essai, qui est intuitive à utiliser et j'aime ça. Cependant, les mêmes principes peuvent être appliqués à toute autre
implémentation d'
OpenID Connect : KeyCloak, IdentityServer et bien d'autres.
Tout d'abord, accédez au
portail Auth0 avec votre compte, créez un locataire
(locataire - «locataire», unité d'isolation logique, pour plus de détails, consultez la documentation - environ la traduction). Allez dans
Applications> Application par défaut , en choisissant
Domaine , comme indiqué dans la capture d'écran ci-dessous. :

Spécifiez ce domaine dans le
resource-manifests/istio/security/auth-policy.yaml
(
source ):
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
Ayant une telle ressource, Pilot
(l'un des trois composants de base de Control Plane dans Istio - environ. Transl.) Configure les Envoyés pour authentifier les demandes avant de les rediriger vers les services:
sa-web-app
et
sa-feedback
. Dans le même temps, la configuration ne s'applique pas aux Envoys du
sa-frontend
, ce qui nous permet de laisser le frontend non authentifié. Pour appliquer une stratégie, exécutez la commande:
$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml policy.authentication.istio.io “auth-policy” created
Revenez à la page et faites une demande - vous verrez qu'elle se termine par
401 Statut
non autorisé . Nous redirigeons maintenant les utilisateurs frontaux vers l'authentification avec Auth0.
Demander une authentification avec Auth0
Pour authentifier les demandes des utilisateurs finaux, vous devez créer une API dans Auth0 qui représentera les services authentifiés (avis, détails et évaluations). Pour créer une API, accédez à
Auth0 Portal> APIs> Create API et remplissez le formulaire:

Les informations importantes ici sont l'
identifiant , que nous utiliserons plus tard dans le script. Écrivons-le pour nous comme ceci:
- Audience : {YOUR_AUDIENCE}
Les autres détails dont nous avons besoin se trouvent sur le portail Auth0 dans la section
Applications - sélectionnez
Test Application (il est créé automatiquement avec l'API).
Ici, nous écrivons:
- Domaine : {YOUR_DOMAIN}
- Identifiant client : {YOUR_CLIENT_ID}
Faites défiler l'
application de test jusqu'à la zone de texte URL de rappel autorisées (URL autorisées pour le rappel), dans laquelle nous indiquons l'URL où l'appel doit être envoyé une fois l'authentification terminée. Dans notre cas, c'est:
http://{EXTERNAL_IP}/callback
Et pour les
URL de déconnexion autorisées (
URL autorisées pour la déconnexion), ajoutez:
http://{EXTERNAL_IP}/logout
Passons au frontend.
Mise à jour frontend
Basculez vers la branche
auth0
du
auth0
[istio-mastery]
. Dans ce thread, le code frontal est modifié pour rediriger les utilisateurs vers Auth0 pour l'authentification et utiliser le jeton JWT dans les demandes d'autres services. Ce dernier est implémenté comme suit (
App.js ):
analyzeSentence() { fetch('/sentiment', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${auth.getAccessToken()}`
Pour convertir le frontend en utilisant les données du locataire dans Auth0, ouvrez
sa-frontend/src/services/Auth.js
et remplacez-y les valeurs que nous avons écrites ci-dessus (
Auth.js ):
const Config = { clientID: '{YOUR_CLIENT_ID}', domain:'{YOUR_DOMAIN}', audience: '{YOUR_AUDIENCE}', ingressIP: '{EXTERNAL_IP}'
L'application est prête. Indiquez votre ID Docker dans les commandes ci-dessous lors de la création et du déploiement des modifications apportées:
$ 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
Essayez l'application! Vous serez redirigé vers Auth0, où vous devrez vous connecter (ou vous inscrire), après quoi vous serez renvoyé à la page à partir de laquelle les demandes déjà authentifiées seront effectuées. Si vous essayez les commandes curl mentionnées dans les premières parties de l'article, vous recevrez un
code d'état 401 , qui indique que la demande n'est pas autorisée.
Passons à l'étape suivante - autoriser les demandes.
Autorisation avec Auth0
L'authentification nous permet de comprendre qui est l'utilisateur, mais pour savoir à quoi il a accès, une autorisation est requise. Istio propose également des outils pour cela.
À titre d'exemple, nous allons créer deux groupes d'utilisateurs (voir le schéma ci-dessous):
- Utilisateurs (utilisateurs) - avec accès uniquement aux services SA-WebApp et SA-Frontend;
- Modérateurs - avec accès aux trois services.
Concept d'autorisationPour créer ces groupes, nous utiliserons l'extension Auth0 Authorization et utiliserons Istio pour leur fournir différents niveaux d'accès.
Installation et configuration de l'autorisation Auth0
Sur le portail Auth0, accédez à
Extensions et installez
Auth0 Authorization . Après l'installation, accédez à l'
extension d'autorisation , puis à la configuration du locataire en cliquant en haut à droite et en sélectionnant l'option de menu appropriée
(Configuration) . Activez
Groupes et cliquez sur le bouton
Règle de publication .

Création de groupe
Dans l'extension d'autorisation, accédez à
Groupes et créez un groupe de
modérateurs . Étant donné que nous considérerons tous les utilisateurs authentifiés comme ordinaires, il n'est pas nécessaire de créer un groupe supplémentaire pour eux.
Sélectionnez le groupe
Modérateurs , cliquez sur
Ajouter des membres , ajoutez votre compte principal. Laissez certains utilisateurs sans groupe pour vous assurer que l'accès leur est refusé. (Les nouveaux utilisateurs peuvent être créés manuellement via le
portail Auth0> Utilisateurs> Créer un utilisateur .)
Ajouter une revendication de groupe pour accéder au jeton
Les utilisateurs sont ajoutés aux groupes, mais ces informations doivent se refléter dans les jetons d'accès. Afin de se conformer à OpenID Connect et de renvoyer en même temps les groupes dont nous avons besoin, le jeton devra ajouter sa
revendication personnalisée . Il est implémenté selon les règles d'Auth0.
Pour créer une règle, accédez au portail Auth0 aux
règles , cliquez sur
Créer une règle et sélectionnez une règle vide dans les modèles.

Copiez le code ci-dessous et enregistrez-le en tant que nouvelle règle d'
ajout de revendication de groupe (
namespacedGroup.js ):
function (user, context, callback) { context.accessToken['https://sa.io/group'] = user.groups[0]; return callback(null, user, context); }
Remarque : ce code prend le premier groupe d'utilisateurs défini dans l'extension d'autorisation et l'ajoute au jeton d'accès en tant que revendication personnalisée (sous son espace de noms, comme requis par Auth0).
Revenez à la page
Règles et vérifiez que vous disposez de deux règles écrites dans l'ordre suivant:
- auth0-autorisation-extension
- Ajouter une revendication de groupe
L'ordre est important car le champ de groupe reçoit de manière asynchrone la
règle d'auth0-autorisation-extension et est ensuite ajouté en tant que revendication par la deuxième règle. Le résultat est un tel jeton d'accès:
{ "https://sa.io/group": "Moderators", "iss": "https://sentiment-analysis.eu.auth0.com/", "sub": "google-oauth2|196405271625531691872" // [ ] }
Vous devez maintenant configurer le proxy Envoy pour vérifier l'accès utilisateur, pour lequel le groupe sera extrait de la revendication (
https://sa.io/group
) dans le jeton d'accès renvoyé. C'est le sujet de la section suivante de l'article.
Configuration des autorisations Istio
Pour l'autorisation de travailler, vous devez activer RBAC pour Istio. Pour ce faire, utilisez la configuration suivante:
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"
Explications:
- 1 - activer RBAC uniquement pour les services et les espaces de noms répertoriés dans le champ
Inclusion
; - 2 - listez la liste de nos services.
Nous appliquons la configuration avec cette commande:
$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml rbacconfig.rbac.istio.io/default created
Désormais, tous les services nécessitent un contrôle d'accès basé sur les rôles. En d'autres termes, l'accès à tous les services est refusé et entraînera une réponse
RBAC: access denied
. Autorisez maintenant l'accès aux utilisateurs autorisés.
Configuration d'accès pour les utilisateurs réguliers
Tous les utilisateurs doivent avoir accès aux services SA-Frontend et SA-WebApp. Mis en œuvre à l'aide des ressources Istio suivantes:
- ServiceRole - définit les droits de l'utilisateur;
- ServiceRoleBinding - Détermine à qui appartient ce ServiceRole.
Pour les utilisateurs ordinaires, autorisez l'accès à certains services (
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: ["*"]
Et par le biais de la
regular-user-binding
appliquez un ServiceRole à tous les visiteurs de la page (
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"
«Tous les utilisateurs» signifie-t-il que les utilisateurs non authentifiés auront accès à SA WebApp? Non, la politique vérifiera la validité du jeton JWT.
Appliquer la configuration:
$ 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
Configuration d'accès pour les modérateurs
Pour les modérateurs, nous voulons permettre l'accès à tous les services (
mod-service-role.yaml ):
apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRole metadata: name: mod-user namespace: default spec: rules: - services: ["*"] paths: ["*"] methods: ["*"]
Mais nous voulons ces droits uniquement pour les utilisateurs dont le jeton d'accès a une revendication
https://sa.io/group
avec la valeur
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"
Appliquer la configuration:
$ 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
En raison de la mise en cache des envoyés, les règles d'autorisation peuvent prendre quelques minutes pour prendre effet. Après cela, vous pouvez vous assurer que les utilisateurs et les modérateurs ont des niveaux d'accès différents.
Conclusion sur cette partie
Eh bien, sérieusement: avez-vous déjà vu une approche plus simple, sans effort, évolutive et sécurisée de l'authentification et de l'autorisation?
Seules trois ressources Istio (RbacConfig, ServiceRole et ServiceRoleBinding) étaient nécessaires pour obtenir un contrôle plus fin de l'authentification et de l'autorisation d'accès des utilisateurs finaux aux services.
De plus, nous avons pris soin de ces questions hors de nos services en tant qu'envoyé, obtenant:
- Réduire la quantité d'exemples de code pouvant inclure des problèmes de sécurité et des bogues;
- réduire le nombre de situations stupides dans lesquelles un point final s'est avéré être accessible de l'extérieur et a oublié de le signaler;
- éliminer la nécessité de mettre à jour tous les services chaque fois qu'un nouveau rôle ou droit est ajouté;
- que les nouveaux services restent simples, sécurisés et rapides.
Conclusion
Istio permet aux équipes de concentrer leurs ressources sur les tâches critiques de l'entreprise sans ajouter de frais généraux aux services, leur redonnant ainsi le statut micro.
L'article (en trois parties) a fourni des connaissances de base et des instructions pratiques prêtes à l'emploi pour commencer à travailler avec Istio dans des projets réels.
PS du traducteur
Lisez aussi dans notre blog: