Jeton dautorisation de la passerelle api
Création d’une autorisation affinée à l’aide d’Amazon Cognito, d’API Gateway et d’IAM
8 septembre 2023 : Il est important de savoir que si vous activez l’inscription d’utilisateurs dans votre groupe d’utilisateurs, n’importe qui sur Internet peut créer un compte et se connecter à vos applications. N’activez pas l’auto-inscription dans votre groupe d’utilisateurs, sauf si vous souhaitez ouvrir votre application pour permettre aux utilisateurs de s’inscrire.
5 juin 2021 : Nous avons mis à jour Figure 1 : Flux de demandes des utilisateurs.
Il est recommandé d’autoriser la fonctionnalité d’une application en fonction de l’appartenance à un groupe. Si vous créez des API avec Amazon API Gateway et que vous avez besoin d’un contrôle d’accès précis pour vos utilisateurs, vous pouvez utiliser Amazon Cognito. Amazon Cognito vous permet d’utiliser des groupes pour créer une collection d’utilisateurs, ce qui est souvent fait pour définir les autorisations pour ces utilisateurs. Dans cet article, je vous montre comment créer une autorisation précise pour protéger vos API à l’aide d’Amazon Cognito, d’API Gateway et d’AWS Identity and Access Management (IAM).
En tant que développeur, vous créez une application orientée client dans laquelle vos utilisateurs vont se connecter à votre application web ou mobile, et en tant que tel, vous exposerez vos API via API Gateway avec des services en amont. Les API peuvent être déployées sur Amazon Elastic Container Service (Amazon ECS), Amazon Elastic Kubernetes Service (Amazon EKS), AWS Lambda ou Elastic Load Balancing, où chacune de ces options transmettra la demande à vos instances Amazon Elastic Compute Cloud (Amazon EC2). De plus, vous pouvez utiliser des services sur site connectés à votre environnement Amazon Web Services (AWS) via un VPN AWS ou AWS Direct Connect. Il est important d’avoir des contrôles précis pour chaque point de terminaison d’API et méthode HTTP. Par exemple, le l’utilisateur doit être autorisé à effectuer une requête GET vers un point de terminaison, mais ne doit pas être autorisé à effectuer une requête POST vers le même point de terminaison. Il est recommandé d’affecter des utilisateurs à des groupes et d’utiliser l’appartenance à des groupes pour autoriser ou refuser l’accès à vos services API.
Présentation de la solution
Dans cet article de blog, vous allez apprendre à utiliser un groupe d’utilisateurs Amazon Cognito en tant qu’annuaire d’utilisateurs et à permettre aux utilisateurs de s’authentifier et d’acquérir le jeton Web JSON (JWT) à transmettre à API Gateway. Le JWT est utilisé pour identifier le groupe auquel l’utilisateur appartient, car le mappage d’un groupe à une stratégie IAM affichera les droits d’accès accordés au groupe.
Remarque : la solution fonctionne de la même manière si Amazon Cognito fédère les utilisateurs avec un fournisseur d’identité externe, tel que Ping, Active Directory ou Okta, au lieu d’être lui-même un fournisseur d’identité. Pour en savoir plus, consultez Ajout d’une connexion à un groupe d’utilisateurs par le biais d’un tiers. De plus, si vous souhaitez utiliser des groupes d’un fournisseur d’identité externe pour accorder l’accès, le contrôle d’accès basé sur les rôles à l’aide d’Amazon Cognito et d’un fournisseur d’identité externe explique comment procéder.
La figure suivante illustre l’architecture de base et le flux d’informations pour les demandes des utilisateurs.
Figure 1 : Flux de demande de l’utilisateur
Passons en revue le flux de demande pour comprendre ce qui se passe à chaque étape, comme illustré à la figure 1 :
- Un utilisateur se connecte et acquiert un jeton d’ID JWT Amazon Cognito, un jeton d’accès et un jeton d’actualisation. Pour en savoir plus sur chaque jeton, consultez Utilisation des jetons avec des groupes d’utilisateurs.
- Une requête RestAPI est effectuée et un jeton de porteur (dans cette solution, un jeton d’accès) est transmis dans les en-têtes.
- API Gateway transmet la demande à un mécanisme d’autorisation Lambda, également appelé mécanisme d’autorisation personnalisé.
- L’autorisateur Lambda vérifie l’Amazon Cognito JWT à l’aide de la clé publique Amazon Cognito. Lors de l’appel initial de Lambda, la clé publique est téléchargée à partir d’Amazon Cognito et mise en cache. Les appels suivants utiliseront la clé publique du cache.
- Le mécanisme d’autorisation Lambda recherche le groupe Amazon Cognito auquel l’utilisateur appartient dans le JWT et effectue une recherche dans Amazon DynamoDB pour obtenir la stratégie mappée au groupe.
- Lambda retourne la stratégie et, éventuellement, le contexte à API Gateway. Le contexte est une carte contenant des paires clé-valeur que vous pouvez transmettre au service en amont. Il peut s’agir d’informations supplémentaires sur l’utilisateur, le service ou tout ce qui fournit des informations supplémentaires au service en amont.
- Le moteur de règles API Gateway évalue la stratégie.
Remarque : Lambda n’est pas responsable de la compréhension et de l’évaluation de la politique. Cette responsabilité incombe à l’individu capacités d’API Gateway.
- La demande est transmise au service.
Remarque : Pour optimiser davantage l’autorisateur Lambda, la stratégie d’autorisation peut être mise en cache ou désactivée, en fonction de vos besoins. En activant le cache, vous pouvez améliorer les performances, car la stratégie d’autorisation sera renvoyée à partir du cache chaque fois qu’il y a une correspondance de clé de cache. Pour plus d’informations, consultez Configurer un mécanisme d’autorisation Lambda à l’aide de la console API Gateway.
Examinons de plus près l’exemple de stratégie suivant qui est stocké dans le cadre d’un élément dans DynamoDB.
Sur la base de cet exemple de politique, l’utilisateur est autorisé à effectuer des appels à l’API petstore. Pour la version v1, l’utilisateur peut faire des requêtes à n’importe quel verbe et à n’importe quel chemin, ce qui est exprimé par un astérisque (*). Pour la v2, l’utilisateur n’est autorisé à faire une requête GET que pour path /status. Pour en savoir plus sur le fonctionnement des stratégies, consultez Sortie d’un mécanisme d’autorisation Lambda Amazon API Gateway.
Pour cette
solution, vous devez disposer des conditions préalables suivantes :
- L’interface de ligne de commande (CLI) AWS installée et configurée pour l’utilisation.
- Python 3.6 ou version ultérieure, pour empaqueter du code Python pour Lambda
Remarque : Nous vous recommandons d’utiliser un environnement virtuel ou virtualenvwrapper pour isoler la solution du reste de votre environnement Python.
- Un rôle ou un utilisateur IAM disposant d’autorisations suffisantes pour créer un pool d’utilisateurs Amazon Cognito, un rôle IAM, une Lambda, une stratégie IAM, une passerelle API et une table DynamoDB.
- Référentiel GitHub de la solution. Vous pouvez le télécharger ou utiliser la commande Git suivante pour le télécharger à partir de votre terminal.
note : Cet exemple de code doit être utilisé pour tester la solution et n’est pas destiné à être utilisé dans un compte de production.
Utilisez la commande suivante pour empaqueter le code Python pour le déploiement sur Lambda.
Pour implémenter cette architecture de référence, vous allez utiliser les services suivants :
Remarque : Cette solution a été testée dans les régions us-east-1, us-east-2, us-west-2, ap-southeast-1 et ap-southeast-2. Avant de sélectionner une région, vérifiez que les services nécessaires, Amazon Cognito, API Gateway et Lambda, sont disponibles dans ces régions.
Passons en revue chaque service et la façon dont ils seront utilisés avant de créer les ressources pour cette solution.
Pool d’utilisateurs Amazon Cognito
Un groupe d’utilisateurs est un annuaire d’utilisateurs dans Amazon Cognito. Avec un groupe d’utilisateurs, vos utilisateurs peuvent se connecter à votre application Web ou mobile via Amazon Cognito. Vous utilisez directement l’annuaire d’utilisateurs Amazon Cognito, car cet exemple de solution crée un utilisateur Amazon Cognito. Toutefois, vos utilisateurs peuvent également se connecter via des fournisseurs d’identité sociaux, OpenID Connect (OIDC) et des fournisseurs d’identité SAML.
Lambda en tant que service d’API de sauvegarde
Initialement, vous créez une fonction Lambda qui sert vos API. API Gateway transmet toutes les demandes à la fonction Lambda pour les exécuter.
Une instance d’API Gateway et une intégration avec Lambda
Ensuite, vous créez une instance d’API Gateway et l’intégrez à la fonction Lambda que vous avez créée. Cette instance d’API Gateway sert de point d’entrée pour le service en amont. La commande bash suivante ci-dessous crée un groupe d’utilisateurs Amazon Cognito, une fonction Lambda et une instance d’API Gateway. La commande configure ensuite l’intégration du proxy avec Lambda et déploie une étape API Gateway.
déployer l’exemple de solution
À partir du répertoire dans lequel vous avez téléchargé l’exemple de code à partir de GitHub, exécutez la commande suivante pour générer un mot de passe utilisateur Amazon Cognito aléatoire et créer les ressources décrites dans la section précédente.
Une fois la commande terminée, elle renvoie un message confirmant la création réussie de la pile.
Pour
vérifier qu’un utilisateur Amazon Cognito a été créé avec succès, exécutez la commande suivante pour ouvrir l’interface utilisateur Amazon Cognito dans votre navigateur, puis connectez-vous avec vos informations d’identification.
Remarque : Lorsque vous exécutez cette commande, elle renvoie le nom d’utilisateur et le mot de passe que vous devez utiliser pour vous connecter.
Vous pouvez également ouvrir la pile CloudFormation et obtenir l’URL de l’interface utilisateur hébergée par Amazon Cognito à partir des sorties de la pile. L’URL est la valeur attribuée à l’attribut CognitoHostedUiUrl.
Figure 2 : Sorties CloudFormation – CognitoHostedUiUrl
Valider Amazon Cognito JWT lors de la connexion
Étant donné que nous n’avons pas installé d’application Web qui répondrait à la demande de redirection, Amazon Cognito redirigera vers localhost, ce qui peut ressembler à une erreur. L’aspect clé est qu’une fois la connexion réussie, il existe une URL similaire à la suivante dans la barre de navigation de votre navigateur :
Tester la configuration de l’API
Avant de protéger l’API avec Amazon Cognito afin que seuls les utilisateurs autorisés puissent y accéder, vérifions que la configuration est correcte et que l’API est servie par API Gateway. La commande suivante envoie une requête curl à API Gateway pour récupérer des données à partir du service API.
Le résultat attendu est que la réponse sera une liste d’animaux de compagnie. Dans ce cas, la configuration est correcte : API Gateway est au service de l’API.
Protéger l’API
Pour protéger votre API, les éléments suivants sont requis :
- DynamoDB pour stocker la stratégie qui sera évaluée par API Gateway afin de prendre une décision d’autorisation.
- Une fonction Lambda pour vérifier le jeton d’accès de l’utilisateur et rechercher la stratégie dans DynamoDB.
Passons en revue tous les services avant de créer les ressources.
Un mécanisme d’autorisation
Lambda est une fonctionnalité d’API Gateway qui utilise une fonction Lambda pour contrôler l’accès à une API. Vous utilisez un mécanisme d’autorisation Lambda pour implémenter un schéma d’autorisation personnalisé qui utilise une stratégie d’authentification par jeton de porteur. Lorsqu’un client envoie une requête à l’une des opérations d’API, la passerelle d’API appelle le mécanisme d’autorisation Lambda. Le mécanisme d’autorisation Lambda prend l’identité de l’appelant en entrée et renvoie une politique IAM en sortie. Le résultat est la politique qui est renvoyé dans DynamoDB et évalué par API Gateway. S’il n’y a pas de politique mappée à l’identité de l’appelant, Lambda génère une politique de refus et la demande est refusée.
DynamoDB
est une base de données clé-valeur et de documents qui offre des performances de l’ordre de l’ordre de l’ordre de la milliseconde à n’importe quelle échelle. C’est idéal pour ce cas d’utilisation afin de garantir que le mécanisme d’autorisation Lambda peut traiter rapidement le jeton porteur, rechercher la politique et la renvoyer à API Gateway. Pour plus d’informations, consultez Contrôler l’accès pour l’appel d’une API.
La dernière étape consiste à créer la table DynamoDB pour que le mécanisme d’autorisation Lambda puisse rechercher la stratégie, qui est mappée à un groupe Amazon Cognito.
La figure 3 illustre un élément dans DynamoDB. Les attributs clés sont les suivants :
- Groupe, qui est utilisé pour rechercher la stratégie.
- Stratégie, qui est renvoyée à API Gateway pour évaluer la stratégie.
Figure 3 : Élément DynamoDB
Sur la base de cette stratégie, l’utilisateur qui fait partie du groupe Amazone Cognito pet-veterinary est autorisé à envoyer des requêtes API à des points de terminaison https:// <domain> / <api-gateway-stage> /petstore/v1/* et https:// <domain> / <api-gateway-stage> /petstore/v2/status pour les requêtes GET uniquement.
Mettre à jour et créer des ressources
Exécutez la commande suivante pour mettre à jour les ressources existantes et créer un mécanisme d’autorisation Lambda et une table DynamoDB.
Testez la configuration du mécanisme d’autorisation personnalisé
Commencez vos tests par la demande suivante, qui n’inclut pas de jeton d’accès.
La demande est refusée avec le message Non autorisé . À ce stade, Amazon API Gateway attend un en-tête nommé Authorization (sensible à la casse) dans la demande. S’il n’y a pas d’en-tête d’autorisation, la demande est refusée avant d’atteindre l’autoriseur lambda. Il s’agit d’un moyen de filtrer les demandes qui n’incluent pas les informations requises.
Utilisez la commande suivante pour le test suivant. Dans ce test, vous réussissez l’en-tête requis, mais le jeton n’est pas valide, car il n’a pas été émis par Amazon Cognito, mais il s’agit d’un simple jeton au format JWT stocké dans ./helper.sh. Pour en savoir plus sur le décodage et la validation d’un jeton JWT, consultez Décodage et vérification d’un jeton JSON Amazon Cognito.
Cette fois-ci, le message est différent. Le mécanisme d’autorisation Lambda a reçu la demande et a identifié le jeton comme non valide et a répondu par le message L’utilisateur n’est pas autorisé à accéder à cette ressource .
Pour réussir une demande à l’API protégée, votre code doit effectuer les étapes suivantes :
- Utilisez un nom d’utilisateur et un mot de passe pour authentifiez-vous auprès de votre groupe d’utilisateurs Amazon Cognito.
- Acquérez les jetons (jeton d’identification, jeton d’accès et jeton d’actualisation).
- Effectuez une requête HTTPS (TLS) à API Gateway et transmettez le jeton d’accès dans les en-têtes.
Avant que la demande ne soit transmise au service d’API, API Gateway reçoit la demande et la transmet au mécanisme d’autorisation Lambda. Le mécanisme d’autorisation effectue les étapes suivantes. Si l’une des étapes échoue, la demande est refusée.
- Récupérez les clés publiques à partir d’Amazon Cognito.
- Mettez en cache les clés publiques afin que le mécanisme d’autorisation Lambda n’ait pas à effectuer d’appels supplémentaires à Amazon Cognito, tant que l’environnement d’exécution Lambda n’est pas arrêté.
- Utilisez des clés publiques pour vérifier le jeton d’accès.
- Recherchez la stratégie dans DynamoDB.
- Retournez la stratégie à API Gateway.
Le jeton d’accès a des revendications telles que en tant que groupes attribués par Amazon Cognito, nom d’utilisateur, utilisation de jeton et autres, comme illustré dans l’exemple suivant (certains champs supprimés).
Enfin, nous allons nous connecter par programmation à l’interface utilisateur d’Amazon Cognito, acquérir un jeton d’accès valide et envoyer une demande à API Gateway. Exécutez la commande suivante pour appeler l’API protégée.
Cette fois, vous recevez une réponse avec des données du service API. Examinons les étapes effectuées par l’exemple de code :
- Le mécanisme d’autorisation Lambda valide le jeton d’accès.
- Le mécanisme d’autorisation Lambda recherche la stratégie dans DynamoDB en fonction du nom de groupe qui a été récupéré à partir du jeton d’accès.
- Le mécanisme d’autorisation Lambda renvoie la stratégie IAM à API Gateway.
- API Gateway évalue la politique IAM et l’effet final est une autorisation.
- API Gateway transmet la demande à Lambda.
- Lambda renvoie la réponse.
Continuons à tester notre politique à partir de la figure 3. Dans le document de stratégie, arn :aws :execute-api :*:*:*/*/GET/petstore/v2/status est le seul point de terminaison pour la version V2, ce qui signifie que les demandes de point de terminaison /GET/petstore/v2/pets doivent être refusées. Exécutez la commande suivante pour tester cela.
Remarque : Maintenant que vous comprenez le contrôle d’accès affiné à l’aide du pool d’utilisateurs Cognito, d’API Gateway et de la fonction lambda, et que vous avez terminé de le tester, vous pouvez exécuter la commande suivante pour nettoyer toutes les ressources associées à cette solution :
Stratégies IAM avancées pour contrôler davantage votre API
Avec IAM, vous pouvez créer des politiques avancées pour affiner l’accès à vos API. Vous pouvez en savoir plus sur les clés de condition qui peuvent être utilisées dans API Gateway, leur utilisation dans une stratégie IAM avec des conditions et sur la façon dont la logique d’évaluation de la stratégie détermine s’il faut autoriser ou Refuser une demande.
Résumé
Dans cet article, vous avez découvert comment IAM et Amazon Cognito peuvent être utilisés pour fournir un contrôle d’accès précis à votre API derrière API Gateway. Vous pouvez utiliser cette approche pour appliquer de manière transparente un contrôle précis à votre API, sans avoir à modifier le code de votre API, et créer des stratégies avancées à l’aide de clés de condition IAM.
Si vous avez des commentaires sur cet article, soumettez-les dans la section Commentaires ci-dessous. Si vous avez des questions sur cet article, lancez un nouveau fil de discussion sur le forum Amazon Cognito ou contactez AWS Support.
Vous souhaitez obtenir plus de contenu pratique, d’actualités et d’annonces de fonctionnalités sur la sécurité AWS ? Suivez-nous sur Twitter.
Artem Lovan
Artem est un architecte de solutions senior basé à New York. Il aide les clients à concevoir et à optimiser des applications sur AWS. Avoir a été impliqué dans l’informatique à plusieurs niveaux, y compris l’infrastructure, la mise en réseau, la sécurité, DevOps et le développement de logiciels.