Configurer l'authentification des utilisateurs avec Anthos Service Mesh

L'authentification des utilisateurs avec Anthos Service Mesh est une solution intégrée pour l'authentification des utilisateurs finaux via un navigateur et le contrôle des accès à vos charges de travail déployées. Elle permet l'intégration aux fournisseurs d'identité (IDP) existants pour l'authentification des utilisateurs, et utilise les API et règles d'autorisation Istio pour la gestion des accès. Il s'agit d'une alternative plus facile à utiliser que l'authentification par jeton Web JSON (JWT) d'Istio.

Une organisation utilisant Anthos Service Mesh pour héberger une application Web à laquelle son personnel doit accéder via un navigateur Web représente un cas d'utilisation classique. De plus, l'organisation doit faire appel à son fournisseur d'identité existant pour gérer les identités des utilisateurs. L'authentification des utilisateurs avec Anthos Service Mesh permet aux utilisateurs de s'authentifier facilement à l'aide d'un flux de connexion et d'autorisation OpenID Connect (OIDC) Web standard. Lorsque l'utilisateur s'authentifie, Anthos Service Mesh applique les règles d'autorisation Istio et, en cas d'autorisation réussie, il transmet l'identité aux charges de travail dans un format d'identifiants sécurisé.

Fonctionnement

L'authentification des utilisateurs avec Anthos Service Mesh introduit un nouveau composant, authservice. Ce composant s'intègre au contrôle d'entrée basé sur Envoy en tant que service d'autorisation externe qui intercepte toutes les requêtes entrantes pour authentification. authservice met en œuvre le côté client du protocole OIDC et permet aux utilisateurs d'accéder aux applications via un navigateur, d'où ils suivent un flux d'authentification et d'autorisation interactif afin d'établir une session de courte durée. authservice met en œuvre des protocoles standards dans l'industrie pour permettre l'intégration à n'importe quel fournisseur d'identité capable d'agir en tant que serveur d'autorisation OIDC. Une fois l'utilisateur authentifié, les informations principales sont encapsulées dans un jeton RCToken au format JWT, qui est signé par authservice, puis transféré vers la couche d'autorisation Istio dans l'entrée. Ce modèle fournit un contrôle d'accès de périmètre pour le trafic entrant dans le maillage. Si l'utilisateur est autorisé à accéder à une ressource, ce jeton RCToken est également transmis aux microservices afin qu'ils obtiennent les informations principales et puissent appliquer un contrôle d'accès précis.

Le schéma suivant illustre l'emplacement de authservice dans le maillage et son lien avec les autres parties du maillage, telles que l'entrée, les charges de travail, le navigateur de l'utilisateur et tout IDP existant.

Authentification de l'utilisateur final

Les administrateurs peuvent installer authservice en tant que module complémentaire sur une installation d'Anthos Service Mesh. Une fois installé, authservice lit la configuration du point de terminaison OIDC et les autres paramètres associés définis dans la ressource personnalisée UserAuth. L'administrateur peut utiliser l'API ExternalAuthorization d'Anthos Service Mesh pour configurer auth_server en tant que filtre sur l'entrée.

Installer le service d'authentification des utilisateurs

Les étapes suivantes expliquent comment configurer le service authservice.

Prérequis

Pour vous assurer que vous remplissez les conditions préalables, procédez comme suit :

Personnaliser l'installation à l'aide de la superposition d'authentification des utilisateurs

Pour installer le service d'authentification des utilisateurs, vous devez personnaliser l'installation ASM afin d'ajouter un fournisseur d'autorisation externe au niveau du maillage.

  1. Obtenez l'exemple de superposition d'authentification des utilisateurs et mettez-le à jour si vous avez personnalisé votre maillage. Nous vous recommandons de conserver ce fichier de superposition dans votre système de gestion de code source.

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/release-0.1/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
    
  2. Suivez la procédure de la section Installer ASM avec un fichier de superposition afin d'utiliser un script fourni par Google pour installer Anthos Service Mesh avec la superposition d'authentification des utilisateurs. Exemple :

    /install_asm \
     --project_id "PROJECT_ID" \
     --cluster_name "CLUSTER_NAME" \
     --cluster_location "CLUSTER_LOCATION" \
     --mode install \
     --enable_all \
     --custom_overlay user-auth-overlay.yaml
    

    Les packages kpt d'authentification des utilisateurs créent une règle AuthorizationPolicy permettant de référencer le fournisseur d'autorisation externe spécifié par pkg/ext-authz.yaml.

Préparer la configuration du client OIDC

Définissez la configuration de votre client OIDC en suivant la procédure ci-dessous. Ce guide utilise Google comme fournisseur d'identité, mais vous pouvez utiliser n'importe quel IdP compatible avec l'authentification OIDC.

  1. Dans la console Google Cloud, accédez à API et services > Identifiants.

    Accéder à "Identifiants"

  2. Accédez à Créer des identifiants, puis sélectionnez ID client OAuth. Si nécessaire, définissez les options de l'écran d'autorisation OAuth, puis configurez les options suivantes :

    • Définissez le paramètre Type d'application sur Application Web.
    • Définissez l'URI de redirection autorisé sur https://localhost:8443/_gcp_anthos_callback.

    Ensuite, cliquez sur Enregistrer.

  3. En outre, enregistrez votre ID client et votre code secret client pour les utiliser ultérieurement :

    export OIDC_CLIENT_ID='<your-client-id>'
    export OIDC_CLIENT_SECRET='<your-client-secret>'
    export OIDC_ISSUER_URI='https://accounts.google.com'
    

Obtenir les packages kpt

Procédez comme suit pour installer la configuration authservice recommandée à partir du dépôt public. Ces commandes récupèrent le conteneur authservice le plus récent et le lancent en tant que pod dans l'espace de noms asm-user-auth. Elles configurent également l'entrée pour qu'elle intercepte toutes les requêtes.

  1. Obtenez le package kpt :

    kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth@release-0.1 .
    cd asm-user-auth/
    

Définir l'URL de redirection et le code secret pour la passerelle d'entrée

OAuth2 nécessite une URL de redirection hébergée sur un point de terminaison protégé par HTTPS. Ces commandes sont fournies à titre d'exemple et simplifient la configuration en générant un certificat autosigné pour la passerelle d'entrée Istio. Un déploiement en production ne doit pas utiliser de certificats autosignés.

  1. Générez un certificat autosigné :

    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
     -days 365 -nodes -subj '/CN=localhost'
    
  2. Créez un code secret permettant à la passerelle d'entrée d'héberger le trafic HTTPS :

    kubectl create -n istio-system secret tls userauth-tls-cert --key=key.pem \
    --cert=cert.pem
    

Appliquer les clés de chiffrement et de signature

authservice a besoin de deux ensembles de clés pour fonctionner correctement. Le premier est constitué d'une clé symétrique pour le chiffrement et le déchiffrement. Cette clé permet de chiffrer l'état de la session avant de la définir en tant que cookie.

Le second ensemble de clés est une paire de clés publique/privée. Cette clé est utilisée pour signer les informations des utilisateurs authentifiés au format JWT en tant que jeton RCToken. La clé publique de cette paire de clés est publiée sur un point de terminaison prédéfini, que les side-cars peuvent utiliser pour valider le jeton JWT.

Le package kpt d'authentification des utilisateurs contient deux exemples de clés permettant une configuration rapide. Toutefois, vous pouvez aussi utiliser le système de gestion de clés de votre choix pour générer ces clés.

  1. Après avoir généré vos clés, mettez les données de clé au même format :

    cat ./samples/rctoken_signing_key.json
    {
      "keys":[
         {
            "kty":"RSA",
            "kid":"rsa-signing-key",
            "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key.
            "useAfter": 1612813735, # unix timestamp
         }
      ]
    }
    
    cat ./samples/cookie_encryption_key.json
    {
      "keys":[
         {
            "kty":"oct",
            "kid":"key-0",
            "K":"YOUR_KEY",
            "useAfter": 1612813735
         }
      ]
    }
    
  2. Créez le secret Kubernetes que authservice va installer dans son propre système de fichiers.

    kubectl create namespace asm-user-auth
    kubectl label namespace asm-user-auth  istio-injection=enabled istio.io/rev=default --overwrite
    kubectl create secret generic secret-key  \
        --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \
        --from-file="rctoken.key"="./samples/rctoken_signing_key.json"  \
        --namespace=asm-user-auth
    

Déployer le service d'authentification des utilisateurs

Les commandes suivantes créent le service d'authentification des utilisateurs et son déploiement dans l'espace de noms asm-user-auth.

  1. Définissez les variables oauth :

    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientID ${OIDC_CLIENT_ID}
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientSecret ${OIDC_CLIENT_SECRET}
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.issuerURI ${OIDC_ISSUER_URI}
    
  2. Appliquez le package kpt :

    kubectl apply -f ./pkg/asm_user_auth_config_v1alpha1.yaml
    kubectl apply -f ./pkg
    

authservice utilise l'objet CRD UserAuthConfig pour fournir l'authentification des utilisateurs finaux. UserAuthConfig est configurable en cours d'exécution. Vous pouvez le mettre à jour pour modifier le comportement de authservice et y configurer des points de terminaison pour tout serveur d'autorisation OIDC. Il contient les champs suivants :

cat pkg/user_auth_config.yaml

apiVersion: security.anthos.io/v1alpha1
kind: UserAuthConfig
metadata:
  name: auth-config
  namespace: user-auth
spec:
  authentication:
  - oidc:
      clientID: "${OIDC_CLIENT_ID}"
      clientSecret: "${OIDC_CLIENT_SECRET}"
      issuerURI: "${OIDC_ISSUER_URI}"
      redirectURIHost: ""
      redirectURIPath: "/_gcp_anthos_callback"
  outputJWTAudience: "test_audience"

Pour en savoir plus sur les champs user_auth_config.yaml, consultez la section Détails de la configuration de l'authentification utilisateur.

Effectuer les tâches post-installation

Les tâches suivantes sont nécessaires une fois que vous avez terminé les étapes d'installation précédentes.

Activer l'authentification des utilisateurs pour vos applications

Cette section explique comment activer l'authentification des utilisateurs en s'appuyant sur l'exemple d'application Online Boutique.

L'authentification des utilisateurs avec Anthos Service Mesh utilise une règle d'autorisation de type CUSTOM pour déclencher le flux OIDC.

Le processus d'installation crée également une passerelle Istio afin de diffuser le trafic HTTPS à l'aide du certificat TLS que vous avez créé dans userauth-tls-cert. Voici la configuration du fichier pkg/gateway.yaml.

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: userauth
  namespace: asm-user-auth
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: userauth-oidc
  namespace: asm-user-auth
spec:
  gateways:
  - userauth
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: /_gcp_anthos_callback
    name: user-auth-route
    route:
    - destination:
        host: authservice
        port:
          number: 10004
  1. Mettez à jour l'application Online Boutique afin qu'elle utilise cette passerelle pour diffuser le trafic HTTPS, et utilisez le transfert de port pour accéder à l'application localement :

    kubectl apply -f./samples/boutique-route.yaml -n demo
    kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system
    

    La passerelle d'entrée sur le port 8443 sera transférée vers localhost afin de rendre l'application accessible localement.

  2. Vérifiez que l'exemple d'application Online Boutique est accessible à l'adresse https://localhost:8443/.

Valider l'authentification des utilisateurs

Pour accéder aux services de l'application Online Boutique, les utilisateurs finaux doivent maintenant se connecter via leur compte Google.

  1. Vérifiez que la page de connexion OIDC s'affiche en accédant à l'adresse https://localhost:8443/.

  2. Une fois connecté, cliquez sur Suivant et vérifiez que cela vous redirige vers la page d'accueil de l'application Online Boutique.

Configurer les règles d'autorisation

Une fois la configuration décrite dans les étapes précédentes terminée, chaque utilisateur sera redirigé via un flux d'authentification Web. À la fin de ce flux, authservice génère un jeton RCToken au format JWT qui permet de transmettre les informations sur l'utilisateur authentifié.

  1. Ajoutez à l'entrée des règles d'autorisation Istio pour vous assurer qu'une vérification d'autorisation est effectuée pour chaque utilisateur authentifié :

    kubectl apply -f ./samples/rctoken-authz.yaml
    
  2. Le fichier rctoken-authz.yaml configure la passerelle d'entrée pour valider le jeton RC émis par authservice et n'accorder l'autorisation que lorsque le jeton JWT contient les champs souhaités, tels que des audiences et des émetteurs.

    Examinez l'exemple de règle d'autorisation suivant :

    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
     name: require-rc-token
     namespace: istio-system
    spec:
     selector:
       matchLabels:
         istio: ingressgateway
     jwtRules:
     - issuer: "authservice.asm-user-auth.svc.cluster.local"
       audiences:
       - "test_audience"
       jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks"
       fromHeaders:
       - name: X-ASM-RCTOKEN
       forwardOriginalToken: true
    ---
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: require-rc-token
     namespace: istio-system
    spec:
     selector:
       matchLabels:
         istio: ingressgateway
     action: ALLOW
     rules:
     - when:
       - key: request.auth.claims[iss]
         values:
         - authservice.asm-user-auth.svc.cluster.local
       - key: request.auth.claims[aud]
         values:
         - test_audience
    

Configurer les paramètres spécifiques à l'environnement

Les étapes précédentes utilisent localhost et un certificat HTTPS autosigné pour une configuration rapide. Pour une utilisation réelle en production, utilisez votre propre domaine, par exemple example.com.

De plus, assurez-vous que les éléments tokenEndpoint et authorizationEndpoint configurés dans l'objet CRD UserAuthConfig disposent d'une route configurée dans VirtualService. Les étapes d'installation précédentes définissent cela dans asm-user-auth/userauth-oidc VirtualService.

Gérer et alterner les clés

authservice utilise deux ensembles de clés. Vous pouvez alterner chaque clé de manière indépendante. Cependant, avant d'alterner les clés, il est important de comprendre comment fonctionne la rotation.

Les deux clés sont au format JSON. Le champ useAfter spécifie l'horodatage définissant le moment à partir duquel la clé doit être utilisée. Lors d'une rotation de clé, vous devez inclure dans le JSON à la fois l'ancienne et la nouvelle clé. Par exemple, dans l'exemple suivant, new-key ne sera utilisé qu'après l'horodatage 1712813735.

{
   "keys":[
      {
         "kty":"RSA",
         "kid":"old-key",
         "K":"...", # k contains a Base64 encoded PEM format RSA signing key.
         "useAfter": 1612813735, # unix timestamp
      }
      {
      "kty":"RSA",
         "kid":"new-key",
         "K":"...", # k contains a Base64 encoded PEM format RSA signing key.
         "useAfter": 1712813735, # unix timestamp
      }
   ]
}

Anthos Service Mesh utilise la clé symétrique pour chiffrer les données de session stockées dans les cookies du navigateur. Pour garantir la validité des sessions existantes, authservice tente le déchiffrement avec toutes les clés de l'ensemble de clés. Lors d'une rotation, authservice utilise la nouvelle clé pour chiffrer les nouvelles sessions et continue à tenter le déchiffrement avec les anciennes clés.

La paire de clés publique/privée est utilisée pour signer RCToken. La clé publique est transmise aux side-cars par istiod pour la validation JWT. Les side-cars doivent impérativement recevoir la nouvelle clé publique avant que authservice ne commence à utiliser la nouvelle clé privée pour signer les jetons RCToken. Pour cela, authservice commence à publier la clé publique immédiatement après son ajout, mais attend un certain temps avant de l'utiliser pour signer des jetons RCToken.

En résumé, lorsque vous effectuez des rotations de clés, nous vous recommandons de procéder comme suit :

  1. Effectuez des rotations de clés régulières ou à la demande selon vos besoins.
  2. Au format JSON, incluez à la fois la clé actuelle et la nouvelle clé. Les nouvelles clés doivent être associées à un horodatage futur. Nous vous recommandons de spécifier un horodatage avec au moins quelques heures d'avance sur l'heure actuelle.
  3. Surveillez et confirmez que les services sont toujours opérationnels après l'utilisation de la nouvelle clé. Attendez au moins un jour après l'utilisation de la nouvelle clé avant de passer à l'étape suivante.
  4. Supprimez les anciennes clés des entrées JSON. Elles ne sont plus nécessaires.

Détails de la configuration de l'authentification utilisateur

Le tableau suivant décrit chaque champ de l'objet CRD :

Nom du champ Description
authentication.oidc Cette section contient la configuration du point de terminaison OIDC et les paramètres utilisés dans le flux OIDC.
authentication.oidc.certificateAuthorityData Il s'agit du certificat SSL du domaine du serveur d'autorisation OIDC.
authentication.oidc.clientID ID client OAuth à utiliser pour le flux d'authentification OIDC.
authentication.oidc.clientSecret Code secret du client OAuth à utiliser pour le flux d'authentification OIDC.
authentication.oidc.issuerURI URI à utiliser comme émetteur dans le jeton RCToken de sortie.
authentication.oidc.redirectURIHost Hôte à utiliser pour l'URI de terminaison OAuth. Si vous laissez ce champ vide, l'hôte de l'URL cible sera utilisé et l'URI de redirection sera assemblé de manière dynamique.
Cette valeur peut être utilisée lorsqu'une session SSO d'authentification utilisateur est souhaitée pour un domaine de niveau supérieur. Par exemple, pour activer l'authentification unique (SSO) entre profile.example.com/ et admin.example.com/, cette valeur peut être définie sur example.com. Cela permettra d'établir une session d'authentification utilisateur sur example.com qui sera partagée entre tous les sous-domaines. Remarque : Si plusieurs domaines sont diffusés à partir du même maillage, example1.com et example2.com, la fonctionnalité ne peut pas être utilisée. Il est recommandé de laisser ce champ vide.
authentication.oidc.redirectURIPath Chemin d'accès au point de terminaison où "authservice" met fin au flux OAuth. Vous devez enregistrer ce chemin d'URI plus l'hôte en tant qu'URI de redirection autorisé sur le serveur d'autorisation de authentication.oidc.clientID.
En outre, cet URI doit être diffusé depuis le même maillage de services et la même entrée que ceux où "authservice" est activé.
authentication.oidc.scopes Champ d'application OAuth qui doit être demandé dans la requête d'authentification.
authentication.oidc.groupsClaim Si "idtoken" contient une revendication de groupes, utilisez ce champ pour indiquer son nom. Si spécifié, le service transmet les données de cette revendication à la revendication "groups" qui figure dans le jeton RCToken de sortie.
authentication.outputJWTAudience Audience du jeton RCToken généré par "authservice". Les side-cars peuvent valider le jeton RCToken entrant vis-à-vis de cette valeur d'audience.

Déploiement multicluster

L'authentification utilisateur d'Anthos Service Mesh est compatible avec le déploiement multicluster. Vous devez déployer l'authentification utilisateur dans chaque cluster comme décrit ci-dessus. Les éléments de la configuration de l'authentification utilisateur, tels que la ressource personnalisée UserAuth, le code secret du client OIDC et les clés de chiffrement, doivent tous être répliqués dans chaque cluster.

Par défaut, la passerelle d'entrée équilibre la charge des requêtes d'authentification sur l'une des instances authservice. Vous pouvez utiliser la règle de destination pour configurer la passerelle d'entrée de manière à ce qu'elle envoie des requêtes au authservice du même cluster et qu'elle ne bascule que vers les authservice des autres clusters.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: authservice-fail-over
  namespace: asm-user-auth
spec:
  host: authservice.asm-user-auth.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      localityLbSetting:
        enabled: true
        failover:
        - from:  us-east
          to: us-west
        - from: us-west
          to: us-east

Comme d'autres configurations, cela doit être configuré dans chaque cluster.

Questions fréquentes

  1. Comment mettre à niveau Anthos Service Mesh avec l'authentification des utilisateurs activée ?

    Suivez le processus de mise à niveau d'Anthos Service Mesh et spécifiez le fichier de superposition user-auth.yaml sur la ligne de commande install_asm.