Lorsqu'une application exécutée dans l'environnement Python 2 envoie une requête à une autre application App Engine, elle peut valider son identité à l'aide de l'API App Engine App Identity. L'application qui reçoit la requête peut utiliser cette identité pour déterminer si elle doit traiter la requête.
Si vos applications Python 3 doivent valider leur identité lors de l'envoi de requêtes à d'autres applications App Engine, vous pouvez utiliser des jetons d'ID OpenID Connect (OIDC) émis et décodés par les API OAuth 2.0 de Google.
Voici un aperçu de l'utilisation des jetons d'ID OIDC pour l'assertion et la validation de l'identité :
- Une application App Engine nommée "Application A" récupère un jeton d'ID à partir de l'environnement d'exécution Google Cloud.
- L'application A ajoute ce jeton à un en-tête de requête juste avant d'envoyer la requête à l'application B, qui est une autre application App Engine.
- L'application B utilise les API OAuth 2.0 de Google pour vérifier la charge utile du jeton. La charge utile décodée contient l'identité validée de l'application A sous la forme de l'adresse e-mail du compte de service par défaut de l'application A.
- L'application B compare l'identité de la charge utile à une liste d'identités auxquelles elle est autorisée à répondre. Si la requête provient d'une application autorisée, l'application B la traite et répond.
Ce guide explique comment mettre à jour vos applications App Engine afin qu'elles utilisent les jetons d'ID OpenID Connect (OIDC) pour valider leur identité, et mettre à jour vos autres applications App Engine afin qu'elles utilisent des jetons d'ID pour vérifier l'identité avant de traiter une requête.
Principales différences entre les API App Identity et OIDC
Les applications de l'environnement d'exécution Python 2 n'ont pas besoin de valider explicitement une identité. Lorsqu'une application utilise les bibliothèques Python
httplib
,urllib
ouurllib2
ou le service de récupération d'URL App Engine pour envoyer des requêtes sortantes, l'environnement d'exécution utilise le service de récupération d'URL App Engine pour effectuer la requête. Si la requête est envoyée au domaineappspot.com
, la récupération d'URL valide automatiquement l'identité de l'application à l'origine de la requête en ajoutant l'en-têteX-Appengine-Inbound-Appid
à la requête. Cet en-tête contient l'ID application de l'application (également appelé ID du projet).Les applications de l'environnement d'exécution Python 3 doivent valider explicitement leur identité en récupérant un jeton d'ID OIDC depuis l'environnement d'exécution Google Cloud et en l'ajoutant à l'en-tête de requête. Vous devrez mettre à jour l'ensemble du code qui envoie des requêtes à d'autres applications App Engine de sorte que les requêtes contiennent un jeton d'ID OIDC.
L'en-tête
X-Appengine-Inbound-Appid
d'une requête contient l'ID de projet de l'application qui a envoyé la requête.La charge utile du jeton d'ID OIDC de Google n'identifie pas directement l'ID du projet de l'application. Au lieu de cela, le jeton identifie le compte de service sur lequel l'application s'exécute, en fournissant l'adresse e-mail de ce compte de service. Vous devez ajouter du code pour extraire le nom d'utilisateur de la charge utile du jeton.
Si ce compte de service est le compte de service App Engine par défaut du projet, l'ID du projet se trouve dans l'adresse e-mail du compte de service. La partie de l'adresse contenant le nom d'utilisateur est identique à l'ID du projet. Dans ce cas, le code de votre application de réception peut effectuer cette recherche dans la liste des ID de projet à partir desquels il autorise les requêtes.
Toutefois, si l'application à l'origine de la requête utilise un compte de service géré par l'utilisateur au lieu du compte de service App Engine par défaut, l'application de réception peut uniquement valider l'identité de ce compte de service, ce qui ne définira pas nécessairement l'ID de projet de l'application à l'origine de la requête. Dans ce cas, l'application de réception devra gérer une liste d'adresses e-mail de comptes de service autorisées au lieu d'une liste d'ID de projets autorisés.
Les quotas pour les appels à l'API URL Fetch sont différents des quotas des API OAuth 2.0 de Google en ce qui concerne l'attribution de jetons. Vous pouvez voir le nombre maximal de jetons que vous pouvez accorder par jour sur l'écran d'autorisation OAuth de la console Google Cloud. URL Fetch, l'API App Identity et les API OAuth 2.0 de Google n'engendrent aucune facturation.
Présentation du processus de migration
Pour migrer vos applications Python afin qu'elles utilisent les API OIDC pour l'assertion et la validation de l'identité :
Dans les applications qui doivent valider l'identité lors de l'envoi de requêtes à d'autres applications App Engine :
Attendez que votre application s'exécute dans un environnement Python 3 pour migrer vers des jetons d'identification.
Bien qu'il soit possible d'utiliser des jetons d'ID dans l'environnement d'exécution Python 2, les étapes d'exécution en Python 2 sont complexes et ne sont requises que temporairement jusqu'à ce que vous mettiez à jour votre application pour qu'elle s'exécute dans l'environnement d'exécution Python 3.
Une fois que votre application est exécutée dans Python 3, mettez à jour l'application pour qu'elle demande un jeton d'ID et l'ajoute à un en-tête de requête.
Dans les applications qui doivent valider l'identité avant de traiter une requête :
Commencez par mettre à niveau vos applications Python 2 pour prendre en charge à la fois les jetons d'ID et les identités de l'API App Identity. Vos applications pourront ainsi valider et traiter les requêtes des applications Python 2 qui utilisent l'API App Identity et les requêtes des applications Python 3 qui utilisent des jetons d'ID.
Une fois que vos applications Python 2 mises à niveau sont stables, migrez-les vers l'environnement d'exécution Python 3. Continuez de prendre en charge à la fois les jetons d'ID et les identités de l'API App Identity tant que vous n'êtes pas certain que les applications n'ont plus besoin de prendre en charge les requêtes provenant d'anciennes applications.
Lorsque vous n'avez plus besoin de traiter les requêtes provenant d'anciennes applications App Engine, supprimez le code qui valide les identités de l'API App Identity.
Après avoir testé vos applications, déployez l'application qui traite les requêtes en premier. Déployez ensuite votre application Python 3 mise à jour qui utilise des jetons d'ID pour valider l'identité.
Valider l'identité
Attendez que votre application s'exécute dans un environnement Python 3, puis procédez comme suit pour mettre à niveau l'application afin de valider l'identité avec des jetons d'ID :
Installez la bibliothèque cliente
google-auth
.Ajoutez du code pour demander un jeton d'ID à partir des API OAuth 2.0 de Google et ajoutez ce jeton à un en-tête de requête avant d'envoyer une requête.
Testez vos mises à jour.
Installer la bibliothèque cliente google-auth
pour les applications Python 3
Pour que la bibliothèque cliente google-auth
soit disponible pour votre application Python 3, créez un fichier requirements.txt
dans le même dossier que votre fichier app.yaml
, puis ajoutez la ligne suivante :
google-auth
Lorsque vous déployez votre application, App Engine télécharge toutes les dépendances définies dans le fichier requirements.txt
.
Pour le développement local, nous vous recommandons d'installer des dépendances dans un environnement virtuel tel que venv.
Ajouter du code pour valider l'identité
Parcourez votre code et trouvez toutes les instances d'envoi de requêtes à d'autres applications App Engine. Mettez à jour ces instances pour qu'elles effectuent les opérations suivantes avant d'envoyer la requête :
Ajoutez les importations suivantes :
from google.auth.transport import requests as reqs from google.oauth2 import id_token
Utilisez
google.oauth2.id_token.fetch_id_token(request, audience)
pour récupérer un jeton d'ID. Incluez les paramètres suivants dans l'appel de méthode :request
: transmettez l'objet de la requête que vous êtes sur le point d'envoyer.audience
: transmettez l'URL de l'application à laquelle vous envoyez la requête. Cela lie le jeton à la requête et empêche l'utilisation du jeton par une autre application.Par souci de clarté et de spécificité, nous vous recommandons de transmettre l'URL
appspot.com
créée par App Engine pour le service spécifique qui reçoit la requête, même si vous utilisez un domaine personnalisé pour l'application.
Dans l'objet de la requête, définissez l'en-tête suivant :
'Authorization': 'ID {}'.format(token)
Exemple :
Tester les mises à jour pour valider l'identité
Pour exécuter votre application localement et vérifier si l'application peut envoyer des jetons d'ID, procédez comme suit :
Suivez ces étapes pour rendre les identifiants du compte de service App Engine par défaut disponibles dans votre environnement local (les API Google OAuth ont besoin de ces identifiants pour générer un jeton d'ID) :
Saisissez la commande
gcloud
suivante afin de récupérer la clé de compte de service pour le compte App Engine par défaut de votre projet :gcloud iam service-accounts keys create ~/key.json --iam-account project-ID@appspot.gserviceaccount.com
Remplacez project-ID par l'ID de votre projet Google Cloud.
Le fichier de clé du compte de service est maintenant téléchargé sur votre ordinateur. Vous pouvez déplacer et renommer ce fichier comme vous le souhaitez. Veillez à stocker ce fichier en toute sécurité, car il peut être utilisé pour s'authentifier en tant que compte de service. Si vous perdez le fichier, ou si le fichier est exposé à des utilisateurs non autorisés, supprimez la clé de compte de service et créez-en une nouvelle.
Saisissez la commande suivante :
<code>export GOOGLE_APPLICATION_CREDENTIALS=<var>service-account-key</var></code>
Remplacez service-account-key par le nom de chemin absolu du fichier contenant la clé de compte de service que vous avez téléchargée.
Dans l'interface système dans laquelle vous avez exporté la variable d'environnement
GOOGLE_APPLICATION_CREDENTIALS
, démarrez votre application Python.Envoyez une requête à partir de l'application et confirmez qu'elle réussit. Si vous ne possédez pas encore d'application pouvant recevoir des requêtes et que vous utilisez des jetons d'ID pour valider les identités :
- Téléchargez l'exemple d'application "entrante".
Dans le fichier
main.py
de l'exemple, ajoutez l'ID de votre projet Google Cloud àallowed_app_ids
. Exemple :allowed_app_ids = [ '<APP_ID_1>', '<APP_ID_2>', 'my-project-id' ]
Exécutez l'exemple mis à jour sur le serveur de développement local de Python 2.
Valider et traiter des requêtes
Pour mettre à niveau vos applications Python 2 afin qu'elles utilisent des jetons d'ID ou des identités de l'API App Identity avant de traiter des requêtes, procédez comme suit :
Installez la bibliothèque cliente google-auth.
Mettez à jour votre code pour effectuer les opérations suivantes :
Si la requête contient l'en-tête
X-Appengine-Inbound-Appid
, utilisez-le pour vérifier l'identité. Les applications s'exécutant dans un ancien environnement d'exécution, tel que Python 2, contiennent cet en-tête.Si la requête ne contient pas l'en-tête
X-Appengine-Inbound-Appid
, recherchez un jeton d'ID OIDC. Si le jeton existe, vérifiez la charge utile du jeton et l'identité de l'expéditeur.
Testez vos mises à jour.
Installer la bibliothèque cliente google-auth pour les applications Python 2
Pour que la bibliothèque cliente google-auth
soit disponible pour votre application Python 2, procédez comme suit :
Créez un fichier
requirements.txt
dans le même dossier que votre fichierapp.yaml
, puis ajoutez la ligne suivante :google-auth==1.19.2
Nous vous recommandons d'utiliser la version 1.19.2 de la bibliothèque cliente Cloud Logging, car elle prend en charge les applications Python 2.7.
Dans le fichier
app.yaml
de votre application, spécifiez la bibliothèque SSL dans la sectionlibraries
si ce n'est pas déjà fait :libraries: - name: ssl version: latest
Créez un répertoire pour stocker les bibliothèques tierces, par exemple
lib/
. Exécutez ensuitepip install
pour installer les bibliothèques dans le répertoire. Exemple :pip install -t lib -r requirements.txt
Créez un fichier
appengine_config.py
dans le même dossier que votre fichierapp.yaml
. Ajoutez le code ci-dessous à votre fichierappengine_config.py
:# appengine_config.py import pkg_resources from google.appengine.ext import vendor # Set path to your libraries folder. path = 'lib' # Add libraries installed in the path folder. vendor.add(path) # Add libraries to pkg_resources working set to find the distribution. pkg_resources.working_set.add_entry(path)
Le fichier
appengine_config.py
de l'exemple précédent suppose que le dossierlib
se trouve dans le répertoire de travail actuel. Si vous ne pouvez pas garantir quelib
sera toujours dans le répertoire de travail actuel, spécifiez le chemin d'accès complet au dossierlib
. Exemple :import os path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib')
Pour le développement local, nous vous recommandons d'installer les dépendances dans un environnement virtuel tel que virtualenv pour Python 2.
Mettre à jour le code pour valider les requêtes
Parcourez votre code et trouvez toutes les instances d'obtention de la valeur de l'en-tête X-Appengine-Inbound-Appid
. Mettez à jour ces instances pour effectuer les opérations suivantes :
Ajoutez les importations suivantes :
from google.auth.transport import requests as reqs from google.oauth2 import id_token
Si la requête entrante ne contient pas l'en-tête
X-Appengine-Inbound-Appid
, recherchez l'en-têteAuthorization
et récupérez sa valeur.La valeur de l'en-tête est au format "ID: jeton".
Utilisez
google.oauth2.id_token.verify_oauth2_token(token, request, audience)
pour valider et récupérer la charge utile de jeton décodée. Incluez les paramètres suivants dans l'appel de méthode :token
: transmettez le jeton que vous avez extrait de la requête entrante.request
: transmettez un nouvel objetgoogle.auth.transport.Request
.audience
: transmettez l'URL de l'application actuelle (l'application qui envoie la requête de validation). Le serveur d'autorisation de Google va comparer cette URL à celle fournie lors de la génération initiale du jeton. Si les URL ne correspondent pas, le jeton ne sera pas validé et le serveur d'autorisation renverra une erreur.
La méthode
verify_oauth2_token
renvoie la charge utile de jeton décodée, qui contient plusieurs paires nom/valeur, y compris l'adresse e-mail du compte de service par défaut pour l'application qui a généré le jeton.Extrayez le nom d'utilisateur de l'adresse e-mail dans la charge utile du jeton.
Le nom d'utilisateur est identique à l'ID de projet de l'application qui a envoyé la requête. Il s'agit de la même valeur que celle précédemment renvoyée dans l'en-tête
X-Appengine-Inbound-Appid
.Si le nom d'utilisateur/l'ID du projet se trouve dans la liste des ID de projet autorisés, traitez la requête.
Exemple :
Tester les mises à jour pour valider l'identité
Pour vérifier que votre application peut utiliser un jeton d'ID ou l'en-tête X-Appengine-Inbound-Appid
afin de valider les requêtes, exécutez l'application dans le serveur de développement local de Python 2, puis envoyez des requêtes à partir d'applications Python 2 (qui utiliseront l'API App Identity) et à partir d'applications Python 3 qui envoient des jetons d'ID.
Si vous n'avez pas mis à jour vos applications pour envoyer des jetons d'ID :
Téléchargez l'exemple d'application "à l'origine de la requête".
Ajoutez des identifiants de compte de service à votre environnement local, comme décrit dans la section Tester les mises à jour pour valider l'identité des applications.
Utilisez les commandes Python 3 standards pour démarrer l'exemple d'application Python 3.
Envoyez une requête à partir de l'exemple d'application et confirmez qu'elle réussit.
Déployer vos applications
Lorsque vous êtes prêt à déployer vos applications, vous devez effectuer les opérations suivantes :
Si les applications s'exécutent sans erreur, répartissez le trafic pour augmenter lentement le trafic de vos applications mises à jour. Surveillez attentivement les éventuels problèmes avant d'acheminer davantage de trafic vers les applications mises à jour.
Utiliser un autre compte de service pour valider l'identité
Lorsque vous demandez un jeton d'ID, la requête utilise l'identité du compte de service App Engine par défaut. Lorsque vous validez le jeton, la charge utile de jeton contient l'adresse e-mail du compte de service par défaut, qui correspond à l'ID du projet de votre application.
Le compte de service App Engine par défaut dispose d'un niveau d'autorisation très élevé par défaut. Il peut afficher et modifier l'ensemble de votre projet Google Cloud. Dans la plupart des cas, l'utilisation de ce compte n'est donc pas appropriée lorsque votre application doit s'authentifier auprès de services cloud.
Toutefois, le compte de service par défaut peut être utilisé en toute sécurité pour valider l'identité de l'application, car vous utilisez uniquement le jeton d'ID pour valider l'identité de l'application qui a envoyé une requête. Les autorisations réelles qui ont été accordées au compte de service ne sont pas prises en compte ni nécessaires au cours de ce processus.
Si vous préférez toujours utiliser un autre compte de service pour vos requêtes de jetons d'ID, procédez comme suit :
Définissez une variable d'environnement nommée
GOOGLE_APPLICATION_CREDENTIALS
sur le chemin d'accès d'un fichier JSON contenant les identifiants du compte de service. Consultez nos recommandations pour savoir comment stocker ces identifiants en toute sécurité.Utilisez
google.oauth2.id_token.fetch_id_token(request, audience)
pour récupérer un jeton d'ID.Lorsque vous validez ce jeton, la charge utile de jeton contient l'adresse e-mail du nouveau compte de service.