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

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 : API keys, Lambda, IAM OpenID Connect et Cognito User Pools. Chaque option propose une méthode de sécurité différente :

  1. APIAutorisation par clé : contrôle la limitation des données non authentifiéesAPIs, offrant ainsi 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. IAMAutorisation : Utilise le processus AWS de signature de la 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 OIDC conformes 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 AWS AppSync GraphQLAPI. Vous spécifiez le type d'autorisation que vous utilisez en spécifiant l'une des valeurs de type d'autorisation suivantes dans votre CLI appel AWS AppSync API ou appel :

  • API_KEY

    Pour utiliser API les clés.

  • 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 consoleCLI, le 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 L'un des moyens de contrôler la régulation des points de terminaison GraphQL non authentifiés consiste à utiliser des clés. API Une API clé est une valeur codée en dur dans votre application qui est générée par le AWS AppSync service lorsque vous créez un point de terminaison GraphQL non authentifié. Vous pouvez faire pivoter les API touches depuis la consoleCLI, depuis ou depuis la AWS AppSync APIréférence.

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

    1. Dans le APIstableau de bord, choisissez votre GraphQLAPI.

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

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

  3. Dans le tableau APIdes clés, choisissez Ajouter une API clé.

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

    1. Pour supprimer une ancienne API clé, sélectionnez-la 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 au AWS CLI. Pour plus d'informations, consultez la section Principes de base de la configuration.

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

    Vous devez saisir deux paramètres pour cette commande particulière :

    1. Celui api-id de votre GraphQLAPI.

    2. La nouvelle name de tesAPI. Vous pouvez utiliser le mêmename.

    3. Leauthentication-type, qui seraAPI_KEY.

    Note

    D'autres paramètres de Region ce type doivent être configurés, mais ils sont généralement définis par défaut sur vos valeurs CLI de configuration.

    Voici un exemple de commande :

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

    Une sortie sera renvoyée dans leCLI. Voici un exemple dans 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" } }

APIles clés sont configurables jusqu'à 365 jours, et vous pouvez prolonger une date d'expiration existante de 365 jours supplémentaires à compter de cette date. APILes clés sont recommandées à des fins de développement ou dans les cas d'utilisation dans lesquels il est possible d'exposer un public en toute sécuritéAPI.

Sur le client, la API clé est spécifiée par l'en-têtex-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 API d'autorisation à 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 personne. API Lorsque vous utilisez des fonctions Lambda pour l'autorisation, les règles suivantes s'appliquent :

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

  • Si les API modes OPENID_CONNECT d'autorisation AWS_LAMBDA et ou le mode AMAZON_COGNITO_USER_POOLS d'autorisation sont activés, le OIDC jeton ne peut pas être utilisé comme jeton AWS_LAMBDA d'autorisation. Notez que le OIDC jeton 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'APIID et du jeton d'authentification. Par défaut, la mise en cache n'est pas activée, mais elle peut être activée au API niveau 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 :

isAuthorized(booléen, obligatoire)

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

Si cette valeur est vraie, l'exécution du GraphQL continueAPI. 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 champ entièrement qualifié ARN 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 ARN formulaire 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(JSONObjet, facultatif)

Un JSON objet 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 JSON objet 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 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 dans les plus brefs délais afin d'optimiser les performances de votre systèmeAPI.

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

Lorsque vous partagez une fonction d'autorisation entre plusieursAPIs, 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 champ non ambigu sous la ARN 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 à celle que API vous souhaitez mettre à jour.

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

    Modifiez l'autorisation API -Level en. AWS Lambda

  3. Choisissez le Région AWS et Lambda ARN pour autoriser les API appels.

    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 l'expression régulière de réponse TTL et 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 à un seul GraphQLAPI, 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 fonction Lambda AWS AppSync API pour utiliser la fonction Lambda donnée ARN 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 du SigV4 et des jetons OIDC

Les méthodes suivantes peuvent être utilisées pour contourner le problème de l'impossibilité d'utiliser votre signature ou votre jeton SigV4 comme OIDC 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 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 OIDC jeton comme jeton d'autorisation Lambda lorsque le mode OPENID_CONNECT d'autorisation ou les modes AWS_LAMBDA d'autorisation AMAZON_COGNITO_USER_POOLS et sont activés pour 'API, AWS AppSync procédez comme suit :

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

  • Pour récupérer le OIDC jeton 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 OIDC jeton 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 API GraphQL. Vous pouvez associer les politiques 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 YourGraphQLApiId de API liste principale de la AppSync console, directement sous le nom de votreAPI. Vous pouvez également le récupérer avec CLI : 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 IAM politique 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 OIDC un service conforme. Votre application peut tirer parti des utilisateurs et des privilèges définis par votre OIDC fournisseur pour contrôler l'accès.

Un émetteur URL est la seule valeur de configuration requise que vous fournissez à AWS AppSync (par exemple,https://auth.example.com). Cela URL doit être adressable. HTTPS AWS AppSync s'ajoute /.well-known/openid-configuration à l'émetteur URL et localise la configuration OpenID conformément à la spécification OpenID Connect https://auth.example.com/.well-known/openid-configuration Discovery. Il prévoit de récupérer un JSON document RFC5785conforme à ce stadeURL. Ce JSON document 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 JWKS le contienne JSON les champs de kty etkid.

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 RSA algorithmes. 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 TTL valeurs pour l'heure émise (iatTTL) et l'heure d'authentification (authTTL) dans votre configuration OpenID Connect pour une validation supplémentaire. 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 OIDC application possède quatre clients avec un client IDs tel que 0A1S2D, 1F4G9H, 1J6L4B, 6, pour valider uniquement les trois premiers clients, vous devez placer 1F4G9H|1J6L4B|6 GS5MG dans le champ ID client. IDs GS5MG

AMAZON_ COGNITO _ USER _ POOLS autorisation

Ce type d'autorisation applique les OIDC jetons 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 JWT jeton 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 GraphQL API via la console ou via la commande suivante : CLI

$ 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 API niveau de 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 qui n'a pas de directive spécifique doit passer le paramètre d'autorisation de API niveau.

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 AWS AppSync GraphQLAPI. 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 AWS AppSync GraphQLAPI, 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 pouvez 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.

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 et des politiques d'accès Identity and Access Management (IAM). 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. Toutefois, lorsque vous utilisez un exemple de modèle intégré à partir de la IAM console pour créer un rôle en dehors de la AWS AppSync console, les autorisations ne seront pas automatiquement limitées à une ressource et vous devez effectuer cette action avant de mettre votre application en production.