Par défaut, seuls les propriétaires et les éditeurs de projets peuvent créer, mettre à jour ou supprimer des fonctions. Pour permettre à d'autres utilisateurs ou groupes d'effectuer ces actions, vous pouvez accorder des rôles aux différents membres à l'aide de Cloud IAM (Cloud Identity and Access Management).
De même, vous pouvez accorder ou limiter la possibilité d'appeler une fonction. Ce comportement diffère pour les fonctions HTTP et les fonctions d'arrière-plan :
- Les fonctions HTTP nécessitent une authentification par défaut. Vous pouvez configurer IAM sur les fonctions HTTP pour spécifier si une fonction autorise les appels non authentifiés.
- Les fonctions d'arrière-plan ne peuvent être appelées que par la source de l'événement auquel elles sont abonnées.
Voici trois cas d'utilisation courants de l'authentification :
Sécuriser l'accès du développeur de sorte que seuls des utilisateurs spécifiques puissent appeler la fonction pendant les tests.
Sécuriser l'accès de fonction à fonction de sorte que seules les fonctions autorisées puissent appeler votre fonction.
Sécuriser l'accès des utilisateurs finaux à une application à partir de clients mobiles ou Web.
Développeurs
Outre les actions administratives telles que la création, la mise à jour et la suppression de fonctions, les développeurs souhaitent souvent tester des fonctions en privé avant de les lancer publiquement.
Lorsque vous utilisez curl
ou des outils similaires, vous devez les traiter comme des requêtes d'utilisateurs finaux et fournir un jeton Google OAuth dans l'en-tête Authorization
des requêtes. Par exemple, vous pouvez obtenir un jeton via gcloud
comme suit :
curl https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME \ -H "Authorization: bearer $(gcloud auth print-identity-token)"
Pour que cette requête fonctionne, le rôle attribué au développeur doit contenir l'autorisation cloudfunctions.functions.invoke
. Par défaut, les rôles Administrateur Cloud Functions et Développeur Cloud Functions disposent de cette autorisation. Consultez la page Rôles IAM de Cloud Functions pour obtenir la liste complète des rôles et des autorisations associées.
Enfin, nous vous recommandons d'attribuer l'ensemble minimal d'autorisations requis pour développer et utiliser vos fonctions. Assurez-vous que les stratégies IAM associées à vos fonctions sont limitées au nombre minimal d'utilisateurs et de comptes de service.
Fonction à fonction
Lors de la création de services qui connectent plusieurs fonctions, il est recommandé de s'assurer que chaque fonction ne peut envoyer des requêtes qu'à certaines autres fonctions.
Par exemple, si vous avez une fonction login
, elle doit pouvoir accéder à la fonction user profiles
, mais probablement pas à la fonction search
.
Commencez par configurer la fonction de réception pour accepter les requêtes provenant de la fonction d'appel :
- Accordez le rôle Demandeur Cloud Functions (
roles/cloudfunctions.invoker
) à l'identité de la fonction d'appel sur la fonction de réception. Par défaut, cette identité estPROJECT_ID@appspot.gserviceaccount.com
.
Console
Accédez à Google Cloud Console :
Cochez la case à côté de la fonction dont vous souhaitez modifier les autorisations.
Cliquez sur Afficher le panneau d'informations dans l'angle supérieur droit pour afficher l'onglet Autorisations, qui contient les rôles attribués à la fonction.
Dans le champ Ajouter des membres, saisissez l'identité d'exécution de la fonction d'appel. Il doit s'agir d'une adresse e-mail de compte de service.
Sélectionnez le rôle Cloud Functions > Demandeur Cloud Functions dans le menu déroulant Sélectionner un rôle.
Cliquez sur Enregistrer.
gcloud
Utilisez la commande gcloud functions add-iam-policy-binding
:
gcloud functions add-iam-policy-binding RECEIVING_FUNCTION \ --member='serviceAccount:CALLING_FUNCTION_IDENTITY' \ --role='roles/cloudfunctions.invoker'
où RECEIVING_FUNCTION
est la fonction de réception et CALLING_FUNCTION_IDENTITY
est l'identité de la fonction d'appel.
Dans la fonction d'appel, vous devez :
créer un jeton d'ID OAuth signé par Google dont l'audience (
aud
) est définie sur l'URL de la fonction de réception ;inclure le jeton d'ID dans un en-tête
Authorization: Bearer ID_TOKEN
de la requête destinée à la fonction.
Node.js
Python
Go
Java
Service à fonction
Si vous appelez une fonction depuis une instance de calcul qui n'a pas accès aux métadonnées de calcul (par exemple, votre propre serveur), vous devez générer manuellement le jeton approprié :
Autosignez un compte de service JWT avec la revendication
target_audience
définie sur l'URL de la fonction de réception.Remplacez le JWT autosigné par un jeton d'ID signé par Google, dont la revendication
aud
doit correspondre à l'URL ci-dessus.Incluez le jeton d'ID dans un en-tête
Authorization: Bearer ID_TOKEN
de la requête destinée à la fonction.
La documentation de Cloud IAP inclut un exemple de code pour illustrer cette fonctionnalité.
Utilisateurs finaux
La plupart des applications gèrent les requêtes des utilisateurs finaux, et il est recommandé de limiter l'accès uniquement aux utilisateurs finaux autorisés. Pour ce faire, vous pouvez intégrer Google Sign-In et attribuer le rôle IAM de demandeur Cloud Functions (roles/cloudfunctions.invoker
) aux utilisateurs, ou mettre en œuvre Firebase Authentication et valider manuellement leurs identifiants.
Google Sign-In
Commencez par activer Google Sign-In dans votre projet :
- Créez un ID client OAuth 2.0 pour votre application dans le même projet que la fonction à sécuriser :
- Accédez à la page Identifiants.
- Sélectionnez le projet avec la fonction que vous souhaitez sécuriser.
- Cliquez sur Créer des identifiants, puis sélectionnez ID client OAuth.
- Vous devrez peut-être configurer votre écran d'autorisation OAuth avant de créer un ID client. Si nécessaire, faites-le pour pouvoir continuer.
- Sélectionnez le type d'application pour lequel vous souhaitez créer des identifiants.
- Ajoutez un nom et des restrictions, le cas échéant. Cliquez ensuite sur Créer.
- Redéployez la fonction que vous souhaitez sécuriser pour garantir que l'ID client correct est défini sur la fonction.
Si vous avez plusieurs ID clients OAuth (par exemple, un pour Android, un pour iOS et un pour le Web), vous devez redéployer votre fonction chaque fois que vous en ajoutez un pour vous assurer que la fonction récupère les modifications. De même, si vous supprimez un ID client, vous devez redéployer votre fonction pour supprimer cet ID client et refuser les requêtes. Tous les ID clients d'un projet seront acceptés.
Dans votre application Web ou mobile, vous devez :
- Obtenez un jeton d'ID pour l'ID client OAuth :
- Android : utilisez Google Sign-In pour obtenir un jeton d'ID.
- iOS : utilisez Google Sign-In pour obtenir un jeton d'ID.
- Web : utilisez Google Sign-In pour obtenir un jeton d'ID.
- inclure le jeton d'ID dans un en-tête
Authorization: Bearer ID_TOKEN
de la requête destinée à la fonction.
Les fonctions Cloud Functions valideront le jeton d'authentification et autoriseront la requête, ou refuseront la requête avant le démarrage de la fonction. Si une requête est refusée, vous ne serez pas facturé pour celle-ci.
Obtenir des informations sur un profil utilisateur
Si vous souhaitez accéder aux informations d'un profil utilisateur, vous pouvez extraire le jeton de l'en-tête Authorization
, décoder le jeton Web JSON et extraire le corps du jeton.
Le corps du jeton d'ID doit contenir les informations suivantes :
{ // These six fields are included in all Google ID Tokens. "iss": "https://accounts.google.com", "sub": "110169484474386276334", "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "iat": "1433978353", "exp": "1433981953", // These seven fields are only included when the user has granted the "profile" // and "email" OAuth scopes to the application. "email": "testuser@gmail.com", "email_verified": "true", "name" : "Test User", "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg", "given_name": "Test", "family_name": "User", "locale": "en" }
Il n'est pas nécessaire de valider le jeton, car il a déjà été validé par IAM.
Dépannage
Si des requêtes utilisateur sont refusées alors qu'elles devraient être autorisées, assurez-vous que le rôle roles/cloudfunctions.invoker
a bien été attribué aux utilisateurs ou que ceux-ci disposent de l'autorisation cloudfunctions.functions.invoke
. Pour en savoir plus à ce sujet, consultez la documentation de référence sur Cloud Functions IAM.
Applications Web, authentification et CORS
Si vous souhaitez créer une application Web sécurisée avec Google Sign-in et Cloud Functions IAM, vous devrez probablement gérer le partage de ressources entre origines multiples (CORS).
Les requêtes CORS préliminaires sont envoyées sans en-tête Authorization
. Elles seront donc refusées pour toutes les fonctions HTTP non publiques. Comme les requêtes préliminaires échouent, la requête principale échouera également.
Pour contourner ce problème, vous pouvez héberger vos fonctions et votre application Web sur le même domaine afin d'éviter les requêtes CORS préliminaires. Sinon, vous devez rendre vos fonctions publiques et gérer le CORS et l'authentification dans le code de la fonction.
Vous pouvez également déployer un proxy Cloud Endpoints et activer le CORS. Si vous souhaitez ajouter des fonctionnalités d'authentification, vous pouvez également activer la validation des jetons d'identification Google, ce qui validera ces mêmes jetons d'authentification.
Firebase Authentication
Si vous souhaitez authentifier les utilisateurs à l'aide d'une combinaison adresse e-mail/mot de passe, d'un numéro de téléphone, d'un compte de réseau social tel que Facebook ou GitHub, ou d'un mécanisme d'authentification personnalisé, vous pouvez utiliser Firebase Authentication.
Commencez par configurer Firebase Authentication dans votre projet et votre fonction :
Configurez Firebase Authentication dans la console Firebase.
Importez le SDK Admin Firebase approprié et configurez-le correctement.
Ajoutez un middleware à votre code pour vérifier les jetons d'ID Firebase.
Déployez votre fonction publiquement.
Dans votre application Web ou mobile, vous devez :
- Utilisez la bibliothèque cliente Firebase Authentication appropriée pour obtenir un jeton d'ID :
- Android : utilisez la méthode
GetTokenResult().getToken()
. - iOS : utilisez la méthode
User.getIDTokenResult(completion:)
. - Web : utilisez la méthode
firebase.User.getIdToken()
.
- Android : utilisez la méthode
- Incluez le jeton d'ID dans un en-tête
Authorization: Bearer ID_TOKEN
de la requête destinée à la fonction.
Vous pouvez également déployer un proxy Cloud Endpoints et activer la validation des jetons d'identification Firebase, ce qui validera ces mêmes jetons d'authentification.
Obtenir des informations sur un profil utilisateur
Si vous souhaitez accéder aux informations d'un profil utilisateur, vous pouvez utiliser le SDK Admin Firebase pour récupérer des données utilisateur.
Clés API
Les clés API identifient l'application cliente et le projet GCP qui appellent votre API, ce qui vous permet d'effectuer une autorisation simple, ainsi que des contrôles de quotas et de limitation de débit.
Les clés API ne sont pas aussi sécurisées que les autres méthodes d'authentification répertoriées ici pour les raisons suivantes :
- Les clés API ont une longue durée de vie. Si une fuite se produit, les clés peuvent être utilisées indéfiniment (ou au moins jusqu'à leur rotation, ce qui oblige tous les clients à les mettre à jour).
- Les clés API étant souvent stockées côté client, elles sont susceptibles d'être réutilisées par des tiers malveillants.
Si vous choisissez d'utiliser des clés API pour le contrôle des quotas et la limitation du débit, nous vous recommandons de les associer à des jetons d'authentification.
Pour configurer l'accès aux clés API, déployez un proxy Cloud Endpoints et activez l'option Configurer les paramètres securityDefinitions
pour activer la validation des clés API.
Étapes suivantes
Découvrez comment gérer l'accès aux fonctions sur lesquelles vous vous authentifiez.