Configuration de l'autorisation et de l'authentification pour sécuriser votre GraphQL APIs - AWS AppSync GraphQL

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Configuration de l'autorisation et de l'authentification pour sécuriser votre GraphQL APIs

AWS AppSync propose les types d'autorisation suivants pour sécuriser GraphQL APIs : clés API, Lambda, IAM, OpenID Connect et groupes d'utilisateurs Cognito. Chaque option propose une méthode de sécurité différente :

  1. Autorisation par clé d'API : contrôle la limitation en cas de non-authentification APIs, fournissant une option de sécurité simple.

  2. Autorisation Lambda : active une logique d'autorisation personnalisée, expliquant en détail les entrées et sorties des fonctions.

  3. Autorisation IAM : utilise le processus AWS de signature version 4 de la version 4 de la solution, permettant un contrôle d'accès précis grâce à des politiques IAM.

  4. Autorisation OpenID Connect : s'intègre aux services conformes à l'OIDC pour l'authentification des utilisateurs.

  5. Groupes d'utilisateurs de Cognito : implémente un contrôle d'accès basé sur les groupes à l'aide des fonctionnalités de gestion des utilisateurs de Cognito.

Types d'autorisation

Il existe cinq manières d'autoriser les applications à interagir avec votre API AWS AppSync GraphQL. Vous spécifiez le type d'autorisation que vous utilisez en spécifiant l'une des valeurs de type d'autorisation suivantes dans votre appel AWS AppSync d'API ou de CLI :

  • API_KEY

    Pour utiliser des clés API.

  • AWS_LAMBDA

    Pour utiliser une AWS Lambda fonction.

  • AWS_IAM

    Pour utiliser les autorisations AWS Identity and Access Management (IAM).

  • OPENID_CONNECT

    Pour utiliser votre fournisseur OpenID Connect.

  • AMAZON_COGNITO_USER_POOLS

    Pour utiliser un groupe d'utilisateurs Amazon Cognito.

Ces types d'autorisation de base fonctionnent pour la plupart des développeurs. Pour des cas d'utilisation plus avancés, vous pouvez ajouter des modes d'autorisation supplémentaires via la console, la CLI et AWS CloudFormation. Pour les modes d'autorisation supplémentaires, AWS AppSync fournit un type d'autorisation qui prend les valeurs répertoriées ci-dessus (c'est-à-dire API_KEYAWS_LAMBDA,AWS_IAM,OPENID_CONNECT, etAMAZON_COGNITO_USER_POOLS).

Lorsque vous spécifiez API_KEYAWS_LAMBDA, ou AWS_IAM en tant que type d'autorisation principal ou par défaut, vous ne pouvez pas les spécifier à nouveau comme l'un des modes d'autorisation supplémentaires. De même, vous ne pouvez pas dupliquer API_KEY AWS_LAMBDA ou AWS_IAM utiliser les modes d'autorisation supplémentaires. Vous pouvez utiliser plusieurs groupes d'utilisateurs Amazon Cognito et fournisseurs OpenID Connect. Toutefois, vous ne pouvez pas utiliser de groupes d'utilisateurs Amazon Cognito ou de fournisseurs OpenID Connect dupliqués entre le mode d'autorisation par défaut et l'un des modes d'autorisation supplémentaires. Vous pouvez spécifier différents clients pour votre groupe d'utilisateurs Amazon Cognito ou votre fournisseur OpenID Connect à l'aide de l'expression régulière de configuration correspondante.

API_KEY autorisation

Les méthodes non authentifiées APIs nécessitent une régulation plus stricte que les méthodes authentifiées. APIs Pour contrôler les limitations des points de terminaison GraphQL non authentifiés, vous pouvez utiliser des clés API. Une clé API est une valeur codée en dur dans votre application, qui est générée par le service AWS AppSync quand vous créez un point de terminaison GraphQL non authentifié. Vous pouvez faire pivoter les clés d'API depuis la console, depuis la CLI ou depuis la référence AWS AppSync d'API.

Console
  1. Connectez-vous à la AppSync console AWS Management Console et ouvrez-la.

    1. Dans le APIs tableau de bord, choisissez votre API GraphQL.

    2. Dans la barre latérale, choisissez Réglages.

  2. Sous Mode d'autorisation par défaut, choisissez la clé API.

  3. Dans le tableau des clés d'API, choisissez Ajouter une clé d'API.

    Une nouvelle clé d'API sera générée dans le tableau.

    1. Pour supprimer une ancienne clé d'API, sélectionnez la clé d'API dans le tableau, puis choisissez Supprimer.

  4. En bas de la page, sélectionnez Save (Enregistrer).

CLI
  1. Si ce n'est pas déjà fait, configurez votre accès à la AWS CLI. Pour plus d'informations, consultez la section Principes de base de la configuration.

  2. Créez un objet d'API GraphQL en exécutant la update-graphql-apicommande.

    Vous devez saisir deux paramètres pour cette commande en particulier :

    1. Celui api-id de votre API GraphQL.

    2. La nouveauté name de votre API. Vous pouvez utiliser le mêmename.

    3. Leauthentication-type, qui seraAPI_KEY.

    Note

    Il existe d'autres paramètres tels Region que ceux qui doivent être configurés, mais ils seront généralement définis par défaut sur les valeurs de configuration de votre CLI.

    Un exemple de commande peut ressembler à ceci :

    aws appsync update-graphql-api --api-id abcdefghijklmnopqrstuvwxyz --name TestAPI --authentication-type API_KEY

    Une sortie sera renvoyée dans la CLI. Voici un exemple en JSON :

    { "graphqlApi": { "xrayEnabled": false, "name": "TestAPI", "authenticationType": "API_KEY", "tags": {}, "apiId": "abcdefghijklmnopqrstuvwxyz", "uris": { "GRAPHQL": "https://s8i3kk3ufhe9034ujnv73r513e.appsync-api.us-west-2.amazonaws.com/graphql", "REALTIME": "wss://s8i3kk3ufhe9034ujnv73r513e.appsync-realtime-api.us-west-2.amazonaws.com/graphql" }, "arn": "arn:aws:appsync:us-west-2:348581070237:apis/abcdefghijklmnopqrstuvwxyz" } }

Les clés API sont configurables pour une durée maximale de 365 jours et vous pouvez prolonger une date d'expiration existante de 365 jours maximum à partir de cette date. Les clés API sont recommandées pour le développement ou pour les cas d'utilisation où il est possible d'exposer une API publique en toute sécurité.

Sur le client, la clé API est spécifiée par l'en-tête x-api-key.

Par exemple, si votre API_KEY a pour valeur 'ABC123', vous pouvez envoyer une requête GraphQL via curl comme suit :

$ curl -XPOST -H "Content-Type:application/graphql" -H "x-api-key:ABC123" -d '{ "query": "query { movies { id } }" }' https://YOURAPPSYNCENDPOINT/graphql

AWS_LAMBDA autorisation

Vous pouvez implémenter votre propre logique d'autorisation d'API à l'aide d'une AWS Lambda fonction. Vous pouvez utiliser une fonction Lambda pour votre autorisateur principal ou secondaire, mais il ne peut y avoir qu'une seule fonction d'autorisation Lambda par API. Lorsque vous utilisez des fonctions Lambda pour l'autorisation, les règles suivantes s'appliquent :

  • Si les modes d'AWS_IAMautorisation AWS_LAMBDA et sont activés dans l'API, la signature SigV4 ne peut pas être utilisée comme jeton AWS_LAMBDA d'autorisation.

  • Si les modes OPENID_CONNECT d'autorisation AWS_LAMBDA et ou le mode d'autorisation sont activés sur l'AMAZON_COGNITO_USER_POOLSAPI, le jeton OIDC ne peut pas être utilisé comme jeton AWS_LAMBDA d'autorisation. Notez que le jeton OIDC peut être un schéma Bearer.

  • Une fonction Lambda ne doit pas renvoyer plus de 5 Mo de données contextuelles pour les résolveurs.

Par exemple, si votre jeton d'autorisation l'est'ABC123', vous pouvez envoyer une requête GraphQL via curl comme suit :

$ curl -XPOST -H "Content-Type:application/graphql" -H "Authorization:ABC123" -d '{ "query": "query { movies { id } }" }' https://YOURAPPSYNCENDPOINT/graphql

Les fonctions Lambda sont appelées avant chaque requête ou mutation. La valeur de retour peut être mise en cache en fonction de l'ID d'API et du jeton d'authentification. Par défaut, la mise en cache n'est pas activée, mais elle peut être activée au niveau de l'API ou en définissant la ttlOverride valeur dans la valeur de retour d'une fonction.

Une expression régulière qui valide les jetons d'autorisation avant l'appel de la fonction peut être spécifiée si vous le souhaitez. Ces expressions régulières sont utilisées pour valider qu'un jeton d'autorisation est au bon format avant que votre fonction ne soit appelée. Toute demande utilisant un jeton ne correspondant pas à cette expression régulière sera automatiquement refusée.

Les fonctions Lambda utilisées pour l'autorisation nécessitent qu'une politique principale leur soit appliquée appsync.amazonaws.com pour permettre de les AWS AppSync appeler. Cette action est effectuée automatiquement dans la AWS AppSync console ; la AWS AppSync console ne supprime pas la politique. Pour plus d'informations sur l'attachement de politiques aux fonctions Lambda, consultez la section Politiques basées sur les ressources dans le Guide du développeur. AWS Lambda

La fonction Lambda que vous spécifiez recevra un événement ayant la forme suivante :

{ "authorizationToken": "ExampleAUTHtoken123123123", "requestContext": { "apiId": "aaaaaa123123123example123", "accountId": "111122223333", "requestId": "f4081827-1111-4444-5555-5cf4695f339f", "queryString": "mutation CreateEvent {...}\n\nquery MyQuery {...}\n", "operationName": "MyQuery", "variables": {} } "requestHeaders": { application request headers } }

L'eventobjet contient les en-têtes envoyés dans la demande par le client d'application à AWS AppSync.

La fonction d'autorisation doit renvoyer au moins isAuthorized un booléen indiquant si la demande est autorisée. AWS AppSync reconnaît les clés suivantes renvoyées par les fonctions d'autorisation Lambda :

Note

La valeur de « operationName in » requestContext pour une opération de WebSocket connexion est définie par AWS AppSync « DeepDish:Connect ».

isAuthorized(booléen, obligatoire)

Une valeur booléenne indiquant si la valeur in authorizationToken est autorisée à effectuer des appels à l'API GraphQL.

Si cette valeur est vraie, l'exécution de l'API GraphQL continue. Si cette valeur est fausse, un UnauthorizedException est augmenté

deniedFields(liste de chaînes, facultatif)

Une liste dont la liste est modifiée de forcenull, même si une valeur a été renvoyée par un résolveur.

Chaque élément est soit un ARN de champ entièrement qualifié sous la forme de, arn:aws:appsync:us-east-1:111122223333:apis/GraphQLApiId/types/TypeName/fields/FieldName soit une forme abrégée deTypeName.FieldName. Le formulaire ARN complet doit être utilisé lorsque deux personnes APIs partagent un autorisateur de fonction Lambda et qu'il peut y avoir une ambiguïté entre les types et les champs communs entre les deux. APIs

resolverContext(Objet JSON, facultatif)

Un objet JSON visible comme $ctx.identity.resolverContext dans les modèles de résolveur. Par exemple, si la structure suivante est renvoyée par un résolveur :

{ "isAuthorized":true "resolverContext": { "banana":"very yellow", "apple":"very green" } }

La valeur des modèles intégrés ctx.identity.resolverContext.apple au résolveur sera « very green ». L'resolverContextobjet ne prend en charge que les paires clé-valeur. Les clés imbriquées ne sont pas prises en charge.

Avertissement

La taille totale de cet objet JSON ne doit pas dépasser 5 Mo.

ttlOverride(entier, facultatif)

Le nombre de secondes pendant lesquelles la réponse doit être mise en cache. Si aucune valeur n'est renvoyée, la valeur de l'API est utilisée. S'il s'agit de 0, la réponse n'est pas mise en cache.

Les autorisateurs Lambda ont un délai d'expiration de 10 secondes. Nous vous recommandons de concevoir des fonctions à exécuter le plus rapidement possible afin d'optimiser les performances de votre API.

Plusieurs AWS AppSync APIs peuvent partager une seule fonction Lambda d'authentification. L'utilisation d'un système d'autorisation entre comptes n'est pas autorisée.

Lorsque vous partagez une fonction d'autorisation entre plusieurs APIs, sachez que les noms de champs abrégés (typename.fieldname) peuvent masquer des champs par inadvertance. Pour lever l'ambiguïté d'un champ dansdeniedFields, vous pouvez spécifier un ARN de champ non ambigu sous la forme de. arn:aws:appsync:region:accountId:apis/GraphQLApiId/types/typeName/fields/fieldName

Pour ajouter une fonction Lambda comme mode d'autorisation par défaut dans : AWS AppSync

Console
  1. Connectez-vous à la AWS AppSync console et accédez à l'API que vous souhaitez mettre à jour.

  2. Accédez à la page des paramètres de votre API.

    Modifiez l'autorisation au niveau de l'API en. AWS Lambda

  3. Choisissez l'ARN Région AWS et Lambda par rapport auxquels autoriser les appels d'API.

    Note

    La politique principale appropriée sera ajoutée automatiquement, ce qui vous permettra AWS AppSync d'appeler votre fonction Lambda.

  4. Définissez éventuellement le TTL de réponse et l'expression régulière de validation du jeton.

AWS CLI
  1. Associez la politique suivante à la fonction Lambda utilisée :

    aws lambda add-permission --function-name "my-function" --statement-id "appsync" --principal appsync.amazonaws.com --action lambda:InvokeFunction --output text
    Important

    Si vous souhaitez que la politique de la fonction soit limitée à une seule API GraphQL, vous pouvez exécuter cette commande :

    aws lambda add-permission --function-name “my-function” --statement-id “appsync” --principal appsync.amazonaws.com --action lambda:InvokeFunction --source-arn “<my AppSync API ARN>” --output text
  2. Mettez à jour votre AWS AppSync API pour utiliser l'ARN de la fonction Lambda donné comme autorisateur :

    aws appsync update-graphql-api --api-id example2f0ur2oid7acexample --name exampleAPI --authentication-type AWS_LAMBDA --lambda-authorizer-config authorizerUri="arn:aws:lambda:us-east-2:111122223333:function:my-function"
    Note

    Vous pouvez également inclure d'autres options de configuration, telles que l'expression régulière du jeton.

L'exemple suivant décrit une fonction Lambda qui illustre les différents états d'authentification et de défaillance qu'une fonction Lambda peut avoir lorsqu'elle est utilisée comme mécanisme d'autorisation : AWS AppSync

def handler(event, context): # This is the authorization token passed by the client token = event.get('authorizationToken') # If a lambda authorizer throws an exception, it will be treated as unauthorized. if 'Fail' in token: raise Exception('Purposefully thrown exception in Lambda Authorizer.') if 'Authorized' in token and 'ReturnContext' in token: return { 'isAuthorized': True, 'resolverContext': { 'key': 'value' } } # Authorized with no f if 'Authorized' in token: return { 'isAuthorized': True } # Partial authorization if 'Partial' in token: return { 'isAuthorized': True, 'deniedFields':['user.favoriteColor'] } if 'NeverCache' in token: return { 'isAuthorized': True, 'ttlOverride': 0 } if 'Unauthorized' in token: return { 'isAuthorized': False } # if nothing is returned, then the authorization fails. return {}

Contourner les limites d'autorisation des jetons SigV4 et OIDC

Les méthodes suivantes peuvent être utilisées pour contourner le problème de l'impossibilité d'utiliser votre signature SigV4 ou votre jeton OIDC comme jeton d'autorisation Lambda lorsque certains modes d'autorisation sont activés.

Si vous souhaitez utiliser la signature SigV4 comme jeton d'autorisation Lambda lorsque AWS_IAM les modes d'autorisation AWS_LAMBDA et sont activés AWS AppSync pour l'API, procédez comme suit :

  • Pour créer un nouveau jeton d'autorisation Lambda, ajoutez des suffixes et/ou des préfixes aléatoires à la signature SigV4.

  • Pour récupérer la signature SigV4 d'origine, mettez à jour votre fonction Lambda en supprimant les préfixes et/ou suffixes aléatoires du jeton d'autorisation Lambda. Utilisez ensuite la signature SigV4 d'origine pour l'authentification.

Si vous souhaitez utiliser le jeton OIDC comme jeton d'autorisation Lambda lorsque OPENID_CONNECT le mode d'autorisation ou AMAZON_COGNITO_USER_POOLS les modes d'autorisation AWS_LAMBDA et sont activés AWS AppSync pour l'API, procédez comme suit :

  • Pour créer un nouveau jeton d'autorisation Lambda, ajoutez des suffixes et/ou des préfixes aléatoires au jeton OIDC. Le jeton d'autorisation Lambda ne doit pas contenir de préfixe de schéma Bearer.

  • Pour récupérer le jeton OIDC d'origine, mettez à jour votre fonction Lambda en supprimant les préfixes et/ou suffixes aléatoires du jeton d'autorisation Lambda. Utilisez ensuite le jeton OIDC d'origine pour l'authentification.

AWS_IAM autorisation

Ce type d'autorisation applique le processus de AWS signature de la version 4 de la signature sur l'API GraphQL. Vous pouvez associer les stratégies d'accès Identity and Access Management (IAM) à ce type d'autorisation. Votre application peut tirer parti de cette association en utilisant une clé d'accès (composée d'un identifiant de clé d'accès et d'une clé d'accès secrète) ou en utilisant des informations d'identification temporaires de courte durée fournies par Amazon Cognito Federated Identities.

Si vous souhaitez un rôle pouvant effectuer toutes les opérations de données :

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "appsync:GraphQL" ], "Resource": [ "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/*" ] } ] }

Vous pouvez le trouver sur la page principale YourGraphQLApiId de liste des API de la AppSync console, directement sous le nom de votre API. Vous pouvez aussi récupérer cet élément via l'interface de ligne de commande : aws appsync list-graphql-apis

Si vous souhaitez limiter l'accès à un nombre limité d'opérations GraphQL, vous pouvez le faire pour les champs racine Query, Mutation et Subscription.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "appsync:GraphQL" ], "Resource": [ "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Query/fields/<Field-1>", "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Query/fields/<Field-2>", "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Mutation/fields/<Field-1>", "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Subscription/fields/<Field-1>" ] } ] }

Par exemple, supposons que vous ayez le schéma suivant et que vous souhaitiez limiter l'accès à l'obtention de tous les billets de blog :

schema { query: Query mutation: Mutation } type Query { posts:[Post!]! } type Mutation { addPost(id:ID!, title:String!):Post! }

La politique IAM correspondante pour un rôle (que vous pourriez associer à un pool d'identités Amazon Cognito, par exemple) se présente comme suit :

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "appsync:GraphQL" ], "Resource": [ "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Query/fields/posts" ] } ] }

OPENID_CONNECT autorisation

Ce type d'autorisation applique les jetons OpenID connect (OIDC) fournis par un service conforme à l'OIDC. Votre application peut tirer parti des utilisateurs et des privilèges définis par votre fournisseur OIDC pour le contrôle des accès.

La seule valeur de configuration obligatoire que vous fournissez à AWS AppSync est une URL d'auteur (par exemple, https://auth.example.com). Cette URL doit être adressable via HTTPS. AWS AppSync s'ajoute /.well-known/openid-configuration à l'URL de l'émetteur et localise la configuration OpenID conformément à la spécification OpenID Connect https://auth.example.com/.well-known/openid-configuration Discovery. Il s'attend à récupérer un document JSON RFC5785conforme à cette URL. Ce document JSON doit contenir une jwks_uri clé pointant vers le document JSON Web Key Set (JWKS) contenant les clés de signature. AWS AppSync nécessite que le JWKS contienne les champs JSON de etkty. kid

AWS AppSync prend en charge un large éventail d'algorithmes de signature.

Algorithmes de signature
RS256
RS384
RS512
PS256
PS384
PS512
HS256
HS384
HS512
ES256
ES384
ES512

Nous vous recommandons d'utiliser les algorithmes RSA. Les jetons émis par le fournisseur doivent inclure l'heure d'émission du jeton (iat) et peuvent inclure son heure d'authentification (auth_time). Vous pouvez fournir des valeurs de durée de vie (TTL) pour l'heure d'émission (iatTTL) et l'heure d'authentification (authTTL) dans votre configuration OpenID Connect afin de renforcer la validation. Si votre fournisseur autorise plusieurs applications, vous pouvez également fournir une expression régulière (clientId) qui est utilisée pour les autorisations par ID client. Lorsque le clientId est présent dans votre configuration OpenID Connect, AWS AppSync valide la réclamation en demandant qu'il corresponde clientId à la réclamation aud ou à la azp réclamation figurant dans le jeton.

Pour valider plusieurs clients, IDs utilisez l'opérateur de pipeline (« | ») qui est un « ou » dans une expression régulière. Par exemple, si votre application OIDC possède quatre clients avec un client IDs tel que 0A1S2D, 1F4G9H, 1J6L4B, 6 MG, pour valider uniquement les trois premiers clients, vous devez placer 1F4G9H|1J6L4B|6 GS5 MG dans le champ ID client. IDs GS5

Autorisation AMAZON_COGNITO_USER_POOLS

Ce type d'autorisation applique les jetons OIDC fournis par les groupes d'utilisateurs Amazon Cognito. Votre application peut exploiter les utilisateurs et les groupes de vos groupes d'utilisateurs et ceux d'un autre AWS compte et les associer à des champs GraphQL pour contrôler l'accès.

Lorsque vous utilisez les groupes d'utilisateurs Amazon Cognito, vous pouvez créer des groupes auxquels les utilisateurs appartiennent. Ces informations sont codées dans un jeton JWT que votre application envoie AWS AppSync dans un en-tête d'autorisation lors de l'envoi d'opérations GraphQL. Vous pouvez utiliser les directives GraphQL sur le schéma pour contrôler les groupes pouvant appeler des résolveurs sur un champ, ainsi que les résolveurs pouvant être appelés, ce qui permet à vos clients de bénéficier d'un accès plus contrôlé.

Supposons, par exemple, que vous ayez le schéma GraphQL suivant :

schema { query: Query mutation: Mutation } type Query { posts:[Post!]! } type Mutation { addPost(id:ID!, title:String!):Post! } ...

Si vous avez deux groupes dans les groupes d'utilisateurs d'Amazon Cognito (les blogueurs et les lecteurs) et que vous souhaitez restreindre le nombre de lecteurs afin qu'ils ne puissent pas ajouter de nouvelles entrées, votre schéma doit ressembler à ceci :

schema { query: Query mutation: Mutation }
type Query { posts:[Post!]! @aws_auth(cognito_groups: ["Bloggers", "Readers"]) } type Mutation { addPost(id:ID!, title:String!):Post! @aws_auth(cognito_groups: ["Bloggers"]) } ...

Notez que vous pouvez omettre la @aws_auth directive si vous souhaitez utiliser par défaut une grant-or-deny stratégie d'accès spécifique. Vous pouvez spécifier la grant-or-deny stratégie dans la configuration du groupe d'utilisateurs lorsque vous créez votre API GraphQL via la console ou via la commande CLI suivante :

$ aws appsync --region us-west-2 create-graphql-api --authentication-type AMAZON_COGNITO_USER_POOLS --name userpoolstest --user-pool-config '{ "userPoolId":"test", "defaultEffect":"ALLOW", "awsRegion":"us-west-2"}'

Utilisation de modes d'autorisation supplémentaires

Lorsque vous ajoutez des modes d'autorisation supplémentaires, vous pouvez configurer directement le paramètre d'autorisation au niveau de l'API AWS AppSync GraphQL (c'est-à-dire le authenticationType champ que vous pouvez configurer directement sur l'GraphqlApiobjet) et il agit comme paramètre par défaut sur le schéma. Cela signifie que tout type n'ayant pas de directive spécifique doit transmettre le paramètre d'autorisation au niveau de l'API.

Au niveau du schéma, vous pouvez spécifier des modes d'autorisation supplémentaires à l'aide de directives sur le schéma. Vous pouvez spécifier des modes d'autorisation sur des champs spécifiques du schéma. Par exemple, pour l'autorisation API_KEY, vous devez utiliser @aws_api_key sur les définitions/champs de type d'objet de schéma. Les directives suivantes sont prises en charge sur les champs de schéma et les définitions de types d'objet :

  • @aws_api_key : permet de spécifier que le champ a l'autorisation API_KEY.

  • @aws_iam : permet de spécifier que le champ a l'autorisation AWS_IAM.

  • @aws_oidc : permet de spécifier que le champ a l'autorisation OPENID_CONNECT.

  • @aws_cognito_user_pools : permet de spécifier que le champ a l'autorisation AMAZON_COGNITO_USER_POOLS.

  • @aws_lambda : permet de spécifier que le champ a l'autorisation AWS_LAMBDA.

Vous ne pouvez pas utiliser la directive @aws_auth avec des modes d'autorisation supplémentaires. @aws_auth fonctionne uniquement dans le contexte de l'autorisation AMAZON_COGNITO_USER_POOLS sans mode d'autorisation supplémentaire. Cependant, vous pouvez utiliser la directive @aws_cognito_user_pools à la place de la directive @aws_auth, en utilisant les mêmes arguments. La principale différence entre les deux est que vous pouvez spécifier @aws_cognito_user_pools sur n'importe quelle définition de champ et de type d'objet.

Pour comprendre comment fonctionnent les modes d'autorisation supplémentaires et comment ils peuvent être spécifiés sur un schéma, examinons le schéma suivant :

schema { query: Query mutation: Mutation } type Query { getPost(id: ID): Post getAllPosts(): [Post] @aws_api_key } type Mutation { addPost( id: ID! author: String! title: String! content: String! url: String! ): Post! } type Post @aws_api_key @aws_iam { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! } ...

Pour ce schéma, supposons qu'il AWS_IAM s'agit du type d'autorisation par défaut sur l'API AWS AppSync GraphQL. Cela signifie que les champs qui n'ont pas de directive sont protégés à l'aide de AWS_IAM. Par exemple, c'est le cas pour le champ getPost sur le type Query. Les directives de schéma vous permettent d'utiliser plusieurs modes d'autorisation. Par exemple, vous pouvez avoir API_KEY configuré un mode d'autorisation supplémentaire sur l'API AWS AppSync GraphQL, et vous pouvez marquer un champ à l'aide de la @aws_api_key directive (par exemple, getAllPosts dans cet exemple). Les directives fonctionnent au niveau du champ. Vous devez donc également accorder à API_KEY l'accès au type Post. Vous pouvez le faire en marquant chaque champ du type Post avec une directive ou en marquant le type Post avec la directive @aws_api_key.

Pour limiter davantage l'accès aux champs du type Post, vous pouvez utiliser des directives sur les champs individuels du type Post, comme illustré ci-après.

Par exemple, vous pouvez ajouter un champ restrictedContent au type Post et limiter l'accès à celui-ci à l'aide de la directive @aws_iam. Les demandes AWS_IAM authentifiées pourront accéder à restrictedContent, mais les demandes API_KEY ne pourront pas y accéder.

type Post @aws_api_key @aws_iam{ id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! restrictedContent: String! @aws_iam } ...

Contrôle précis des accès

Les informations précédentes montrent comment limiter ou accorder l'accès à certains champs GraphQL. Si vous voulez définir des contrôles d'accès sur les données en fonction de certaines conditions (par exemple, en fonction de l'utilisateur effectuant l'appel et du fait qu'il est ou non propriétaire des données), vous pouvez utiliser des modèles de mappage dans vos résolveurs. Vous pouvez également utiliser une logique métier plus complexe, dont vous trouverez la description dans Filtrage des informations.

Cette section explique comment définir les contrôles d'accès à vos données à l'aide d'un modèle de mappage du résolveur DynamoDB.

Avant de poursuivre, si vous n'êtes pas familiarisé avec les modèles de mappage dans AWS AppSync, vous souhaiterez peut-être consulter la référence du modèle de mappage Resolver et la référence du modèle de mappage Resolver pour DynamoDB.

Dans l'exemple suivant utilisant DynamoDB, supposons que vous utilisiez le schéma de billet de blog précédent et que seuls les utilisateurs ayant créé un article soient autorisés à le modifier. Le processus d'évaluation devrait consister pour l'utilisateur à obtenir des informations d'identification dans son application, à l'aide de groupes d'utilisateurs Amazon Cognito, par exemple, puis à transmettre ces informations d'identification dans le cadre d'une opération GraphQL. Le modèle de mappage remplace alors une valeur des informations d'identification (comme le nom utilisateur) dans une instruction conditionnelle qui sera ensuite comparée à une valeur dans votre base de données.

Diagram showing authentication flow from user login to database operation using Services AWS.

Pour ajouter cette fonctionnalité, ajoutez un champ GraphQL editPost comme suit :

schema { query: Query mutation: Mutation } type Query { posts:[Post!]! } type Mutation { editPost(id:ID!, title:String, content:String):Post addPost(id:ID!, title:String!):Post! } ...

Le modèle de mappage de résolveur pour editPost (illustré dans un exemple à la fin de cette section) doit effectuer une vérification logique par rapport à votre magasin de données afin que seul l'utilisateur ayant créé un billet puisse le modifier. Comme il s'agit d'une opération de modification, elle correspond à une opération UpdateItem dans DynamoDB. Vous pouvez effectuer une vérification conditionnelle avant d'exécuter cette action, en utilisant le contexte transmis pour la validation de l'identité de l'utilisateur. Ce dernier se trouve dans un objet Identity qui a les valeurs suivantes :

{ "accountId" : "12321434323", "cognitoIdentityPoolId" : "", "cognitoIdentityId" : "", "sourceIP" : "", "caller" : "ThisistheprincipalARN", "username" : "username", "userArn" : "Sameasabove" }

Pour utiliser cet objet dans un appel DynamoDBUpdateItem, vous devez enregistrer les informations d'identité de l'utilisateur dans le tableau à des fins de comparaison. Tout d'abord, votre mutation addPost doit contenir le créateur. Ensuite, votre mutation editPost doit effectuer la vérification conditionnelle avant la mise à jour.

Voici un exemple de code de résolution addPost qui stocke l'identité de l'utilisateur sous forme de Author colonne :

import { util, Context } from '@aws-appsync/utils'; import { put } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { id: postId, ...item } = ctx.args; return put({ key: { postId }, item: { ...item, Author: ctx.identity.username }, condition: { postId: { attributeExists: false } }, }); } export const response = (ctx) => ctx.result;

Notez que l'attribut Author est renseigné à partir de l'objet Identity, qui provient de l'application.

Enfin, voici un exemple de code de résolution poureditPost, qui met à jour le contenu du billet de blog uniquement si la demande provient de l'utilisateur qui a créé le billet :

import { util, Context } from '@aws-appsync/utils'; import { put } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { id, ...item } = ctx.args; return put({ key: { id }, item, condition: { author: { contains: ctx.identity.username } }, }); } export const response = (ctx) => ctx.result;

Cet exemple utilise un PutItem qui remplace toutes les valeurs plutôt que anUpdateItem, mais le même concept s'applique au bloc d'conditioninstructions.

Filtrer les informations

Il peut arriver que vous ne puissiez pas contrôler la réponse de votre source de données, mais que vous ne souhaitiez pas envoyer des informations inutiles aux clients sur la réussite d'une opération de lecture ou d'écriture sur la source de données. Dans ce cas, vous pouvez filtrer les informations à l'aide d'un modèle de mappage de réponse.

Supposons, par exemple, que vous ne disposiez pas d'un index approprié dans la table DynamoDB de votre billet de blog (tel qu'un index sur). Author Vous pouvez utiliser le résolveur suivant :

import { util, Context } from '@aws-appsync/utils'; import { get } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { return get({ key: { ctx.args.id } }); } export function response(ctx) { if (ctx.result.author === ctx.identity.username) { return ctx.result; } return null; }

Le gestionnaire de demandes récupère l'élément même si l'appelant n'est pas l'auteur qui a créé le message. Pour éviter que cela ne renvoie toutes les données, le gestionnaire de réponses vérifie que l'appelant correspond à l'auteur de l'article. Si l'appelant ne correspond pas à ce contrôle, seule une réponse null est renvoyée.

Accès à une source de données

AWS AppSync communique avec les sources de données à l'aide des rôles Identity and Access Management (IAM) et des politiques d'accès. Si vous utilisez un rôle existant, une politique de confiance doit être ajoutée AWS AppSync pour pouvoir assumer le rôle. La relation d'approbation doit ressembler à ce qui suit :

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

Il est important de définir la stratégie d'accès en fonction du rôle, afin de n'avoir que les autorisations nécessaires pour agir sur l'ensemble minimal de ressources nécessaires. Lorsque vous utilisez la AppSync console pour créer une source de données et créer un rôle, cela se fait automatiquement pour vous. Cependant, lorsque vous utilisez un modèle d'exemple intégré de la console IAM pour créer un rôle en dehors de la console AWS AppSync, les permissions ne seront pas automatiquement limitées à une ressource et vous devez effectuer cette action avant de déplacer votre application en production.