Découvrez comment appeler des fonctions Cloud authentifiées

1. Introduction

Présentation

Cloud Functions est une solution de calcul légère permettant aux développeurs de créer des fonctions autonomes à usage unique qui peuvent être déclenchées via HTTPS ou répondu à des CloudEvents sans avoir à gérer de serveur ni d'environnement d'exécution.

Il existe deux approches principales pour contrôler les appels à Cloud Functions: sécuriser l'accès en fonction de l'identité et sécuriser l'accès à l'aide de contrôles des accès basés sur le réseau. Cet atelier de programmation se concentre sur la première approche et vous présente trois scénarios permettant de sécuriser l'accès en fonction de l'identité afin d'appeler une fonction:

  1. Utilisez votre jeton d'identité gcloud pour appeler une fonction pour le développement local et à des fins de test
  2. Emprunter l'identité d'un compte de service lors du développement et des tests en local afin d'utiliser les mêmes identifiants qu'en production
  3. Utilisez les bibliothèques clientes Google pour gérer l'authentification auprès des API Google Cloud (ex. : Lorsqu'un service doit appeler une fonction

Points abordés

  • Configurer l'authentification sur une fonction Cloud et vérifier qu'elle a été correctement configurée
  • Appelez une fonction authentifiée à partir d'un environnement de développement local en fournissant le jeton de votre identité gcloud.
  • Créer un compte de service et lui attribuer le rôle approprié pour appeler une fonction
  • emprunter l'identité d'un service à partir d'un environnement de développement local disposant des rôles appropriés pour appeler une fonction.

2. Préparation

Prérequis

  • Vous êtes connecté à la console Cloud
  • Vous avez déjà déployé une fonction Cloud de 2e génération déclenchée par HTTP
  • (Facultatif) Pour le troisième scénario, nous utilisons Node.js et npm comme exemple pour cet atelier de programmation, mais vous pouvez utiliser n'importe quel environnement d'exécution compatible avec les bibliothèques clientes Google Auth.

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire vous explique de quoi il s'agit. Si un écran intermédiaire s'est affiché, cliquez sur Continuer.

9c92662c6a846a5c.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

9f0e51b578fecce5.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes authentifié et le projet est défini sur votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Créer et tester une fonction Cloud authentifiée

Cet atelier de programmation suit les mêmes instructions que le guide de démarrage rapide de la console pour Cloud Functions, à une exception notable près: votre fonction nécessite une authentification.

Exiger une authentification signifie que le principe qui appelle la fonction doit disposer des rôles Demandeur Cloud Functions (et Demandeur Cloud Run pour 2e génération). Sinon, la fonction renverra une erreur 403 Forbidden. Dans cet atelier de programmation, vous allez découvrir comment attribuer les rôles de demandeur appropriés à un principe.

Créer la fonction authentifiée

Voici les étapes à suivre pour utiliser la console Cloud:

  1. Accédez à la page Présentation de Cloud Functions, puis cliquez sur Créer une fonction.
  2. Sous l'option Environnement, sélectionnez 2e génération.
  3. Nommez la fonction my-authenticated-function.
  4. Dans le champ "Authentification", conservez la valeur par défaut Exiger l'authentification.

936eee0d5930d12b.png

  1. Cliquez sur Suivant.
  2. Pour cet atelier de programmation, vous pouvez choisir n'importe quel langage
  3. Appuyez ensuite sur Déployer.

Le déploiement de votre fonction prend environ une minute.

Configurez des variables d'environnement locales pour des commandes gcloud simplifiées

Tout d'abord, vous allez créer quelques variables d'environnement pour améliorer la lisibilité des commandes gcloud utilisées dans cet atelier de programmation.

Vous devez spécifier la région de votre fonction. Cet exemple utilise us-central1.

REGION="us-central1"

Vous pouvez ensuite enregistrer l'URL de la fonction en tant que variable d'environnement pour l'utiliser ultérieurement.

PROJECT_ID=$(gcloud config get-value project)
FUNCTION_URL="$(gcloud functions describe my-authenticated-function --gen2 --region us-central1 --format='get(serviceConfig.uri)')"

Vérifier que la fonction nécessite une authentification en essayant de l'appeler en tant qu'appelant anonyme

Vous allez appeler la fonction sans authentification pour vérifier que vous recevez une erreur 403 attendue.

À partir d'une ligne de commande, exécutez la commande curl suivante:

curl $FUNCTION_URL

Le résultat suivant s'affiche:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/</code> from this server.</h2>
<h2></h2>
</body></html>

Vous êtes maintenant prêt à découvrir trois scénarios dans lesquels vous pouvez appeler votre fonction en fournissant une authentification.

4. Scénario 1: Utiliser votre jeton d'identité gcloud

En tant que développeur, vous avez besoin d'un moyen de tester votre fonction pendant que vous la développez en local. Dans cette section, vous allez effectuer un test rapide pour vérifier que la fonction est correctement authentifiée à l'aide de votre propre identité.

Vérifiez que vous êtes authentifié avec gcloud en exécutant la commande suivante:

gcloud auth list

Un astérisque doit s'afficher à côté de votre identité active, par exemple:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Après avoir vérifié que vous utilisez la bonne identité, enregistrez l'adresse e-mail du compte dans une variable d'environnement.

ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")

Vous trouverez plus d'informations sur la configuration de gcloud init et sur gcloud auth login dans la documentation.

Ensuite, appelez la fonction et transmettez-lui votre jeton d'identité.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"

Le résultat s'affiche:

Hello World!

Dépannage

Si vous recevez une erreur "403 Accès interdit", assurez-vous que votre identité dispose du rôle Demandeur Cloud Functions ou Demandeur Cloud Run pour les fonctions de 2e génération. Vous pouvez utiliser la console IAM pour vérifier les rôles attribués à un compte principal.

Bien que l'utilisation de votre propre jeton d'identité soit un moyen rapide de tester votre fonction pendant le développement, l'appelant de votre fonction authentifiée aura besoin des rôles appropriés. sinon l'appelant recevra une erreur "403 Forbidden".

Vous devez suivre le principe du moindre privilège en limitant le nombre d'identités et de comptes de service disposant de rôles pour appeler la fonction.

en créant un compte de service et en lui attribuant les rôles nécessaires.

5. Scénario 2: Emprunter l'identité d'un compte de service

Dans ce scénario, vous empruntez l'identité (c'est-à-dire, vous assumez les autorisations de) un compte de service pour appeler une fonction lors du développement et des tests en local. En empruntant l'identité d'un compte de service, vous pouvez tester votre fonction avec les mêmes identifiants qu'en production.

Ainsi, non seulement vous vérifierez les rôles, mais vous appliquerez également le principe du moindre privilège en vous évitant d'avoir à attribuer le rôle Demandeur de fonction Cloud à d'autres identités uniquement à des fins de test local.

Pour les besoins de cet atelier de programmation, vous allez créer un compte de service doté uniquement de rôles pour appeler la fonction que vous avez créée dans cet atelier de programmation.

Créer un compte de service

Tout d'abord, vous allez créer deux variables d'environnement supplémentaires pour représenter les comptes de service utilisés dans les commandes gcloud.

SERVICE_ACCOUNT_NAME="invoke-functions-codelab"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

Vous allez maintenant créer le compte de service.

gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
  --display-name="Cloud Function Authentication codelab"

Et accordez au compte de service le rôle de demandeur de fonction Cloud

gcloud functions add-iam-policy-binding my-authenticated-function \
  --region=us-central1 --gen2 \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/cloudfunctions.invoker'

Appeler la fonction en usurpant l'identité du compte de service

Pour cela, vous emprunterez l'identité du compte de service nouvellement créé en obtenant son jeton d'ID.

Ajouter les rôles requis pour l'emprunt d'identité

Pour emprunter l'identité d'un compte de service, votre compte utilisateur doit disposer du rôle Créateur de jetons du compte de service (roles/iam.serviceAccountTokenCreator) afin de générer un jeton d'ID pour le compte de service.

gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS  \
  --member user:$ACCOUNT_EMAIL \
  --role='roles/iam.serviceAccountTokenCreator'

Utiliser le jeton d'ID du compte de service

Vous pouvez maintenant appeler la fonction en transmettant le jeton d'ID du compte de service.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)" 

Le résultat suivant s'affiche:

WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com].
Hello World!

6. Scénario 3: Utiliser les bibliothèques clientes Google

Dans cette dernière partie de l'atelier de programmation, vous allez exécuter un petit service localement pour générer un jeton d'ID pour un compte de service, puis appeler la fonction par programmation à l'aide des bibliothèques clientes Google Auth et des identifiants par défaut de l'application. Pour en savoir plus sur les bibliothèques clientes Google, consultez la section d'explication sur les bibliothèques clientes de la documentation.

L'utilisation de la stratégie ADC est particulièrement importante lorsque vous souhaitez écrire et tester une fonction en local (par exemple, sur votre ordinateur portable, dans Cloud Shell, etc.) tout en interagissant avec d'autres ressources Google Cloud (par exemple, Cloud Storage, l'API Vision, etc.). Dans cet exemple, vous verrez comment faire en sorte qu'un service appelle une autre fonction nécessitant une authentification. Pour en savoir plus sur l'ADC et le développement local, consultez l'article de blog Comment développer et tester vos fonctions Cloud en local | Blog Google Cloud

Exécuter la commande gcloud pour emprunter l'identité d'un compte de service

ADC trouve automatiquement les identifiants en fonction de l'environnement de l'application et les utilise pour s'authentifier auprès des API Google Cloud. L'option –impersonate-service-account vous permet d'emprunter l'identité d'un compte de service pour l'authentification auprès des API Google Cloud.

Pour emprunter l'identité d'un compte de service, exécutez la commande suivante:

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

Vous allez maintenant exécuter des commandes gcloud avec ce compte de service, et non avec votre identité.

Créer et exécuter un service pour appeler une fonction authentifiée

Chaque environnement d'exécution possède sa propre bibliothèque cliente Google Auth que vous pouvez installer. Cet atelier de programmation vous explique comment créer et exécuter une application Node.js en local.

Voici les étapes à suivre pour Node.js:

  1. Créer une application Node.js
npm init
  1. Installer la bibliothèque cliente Google Auth
npm install google-auth-library
  1. Créer un fichier index.js
  2. Récupérez l'URL de votre fonction Cloud, que vous ajouterez à votre code à l'étape suivante.
echo $FUNCTION_URL
  1. Ajoutez le code suivant à index.js. Veillez à remplacer la variable targetAudience par l'URL de votre fonction Cloud.

index.js

// Cloud Functions uses your function's url as the `targetAudience` value

const targetAudience = '<YOUR-CLOUD-FUNCTION-URL>';

// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal

const url = targetAudience;

const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();

async function request() {
    console.info(`request ${url} with target audience ${targetAudience}`);

    // this call retrieves the ID token for the impersonated service account
    const client = await auth.getIdTokenClient(targetAudience);

    const res = await client.request({ url });
    console.info(res.data);
}

request().catch(err => {
    console.error(err.message);
    process.exitCode = 1;
});
  1. Exécuter l'application
node index.js

Le message "Hello World!" doit s'afficher.

Dépannage

Si vous voyez une erreur Autorisation "iam.serviceAccounts.getOpenIdToken" sur la ressource (ou celle-ci n'existe peut-être pas). Veuillez patienter quelques minutes, le temps que le rôle Créateur de jetons du compte de service se propage.

Si vous avez reçu le message d'erreur "Impossible de récupérer le jeton d'ID dans cet environnement, utilisez GCE" ou définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur un fichier JSON d'identifiants de compte de service, vous avez peut-être oublié d'exécuter la commande.

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

7. Félicitations !

Félicitations ! Vous avez terminé cet atelier de programmation.

Nous vous recommandons de consulter la documentation sur la sécurisation des fonctions Cloud Functions.

Nous vous recommandons également cet article de blog sur le développement local avec Cloud Functions pour découvrir comment développer et tester votre fonction Cloud dans votre environnement de développement local.

Points abordés

  • Configurer l'authentification sur une fonction Cloud et vérifier qu'elle a été correctement configurée
  • Appelez une fonction authentifiée à partir d'un environnement de développement local en fournissant le jeton de votre identité gcloud.
  • Créer un compte de service et lui attribuer le rôle approprié pour appeler une fonction
  • emprunter l'identité d'un service à partir d'un environnement de développement local disposant des rôles appropriés pour appeler une fonction.

8. Effectuer un nettoyage

Pour éviter des frais accidentels (par exemple, cette fonction Cloud est invoquée plus de fois que votre allocation mensuelle d'appel de fonctions Cloud dans le niveau sans frais), vous pouvez supprimer la fonction Cloud ou supprimer le projet créé à l'étape 2.

Pour arrêter d'emprunter l'identité du compte de service, vous pouvez vous reconnecter à l'aide de votre identité:

gcloud auth application-default login

Pour supprimer la fonction Cloud, accédez à la console Cloud de la fonction Cloud à l'adresse https://console.cloud.google.com/functions/. Assurez-vous que le projet que vous avez créé à l'étape 2 est le projet actuellement sélectionné.

Sélectionnez la fonction my-authenticated-function que vous avez déployée précédemment. Appuyez ensuite sur Supprimer.

Si vous choisissez de supprimer l'intégralité du projet, vous pouvez accéder à https://console.cloud.google.com/cloud-resource-manager, sélectionner le projet que vous avez créé à l'étape 2, puis cliquer sur "Supprimer". Si vous supprimez le projet, vous devrez le modifier dans Cloud SDK. Vous pouvez afficher la liste de tous les projets disponibles en exécutant gcloud projects list.