GraphQL を保護するための認証と認可の設定 APIs - AWS AppSync

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

GraphQL を保護するための認証と認可の設定 APIs

AWS AppSync では、GraphQL をセキュア化するために、APIsAPIキー、Lambda、、IAMOpenID Connect、および Cognito ユーザープールの認証タイプを提供しています。各オプションは、異なるセキュリティ方法を提供します。

  1. API キー認証: 認証されていない のスロットリングを制御しAPIs、シンプルなセキュリティオプションを提供します。

  2. Lambda 認証: カスタム認証ロジックを有効にし、関数の入力と出力を詳細に説明します。

  3. IAM 認証 : AWSの署名バージョン 4 の署名プロセスを使用して、IAMポリシーによるきめ細かなアクセスコントロールを可能にします。

  4. OpenID Connect 認証: ユーザー認証用の OIDC準拠サービスと統合します。

  5. Cognito ユーザープール: Cognito のユーザー管理機能を使用してグループベースのアクセスコントロールを実装します。

認証タイプ

アプリケーションが GraphQL とやり取りすることを許可する方法は 5 つあります AWS AppSyncAPI。使用する認証タイプを指定するには、 または CLI呼び出しで次のいずれかの認証タイプ値を指定します AWS AppSync API。

  • API_KEY

    API キーを使用する場合。

  • AWS_LAMBDA

    AWS Lambda 関数を使用する場合。

  • AWS_IAM

    AWS Identity and Access Management (IAM) アクセス許可を使用する場合。

  • OPENID_CONNECT

    OpenID Connect プロバイダーを使用する場合。

  • AMAZON_COGNITO_USER_POOLS

    Amazon Cognito ユーザープールを使用する場合。

これらの基本的な承認タイプは、ほとんどの開発者に有効です。より高度なユースケースでは、コンソール、、CLIおよび を使用して追加の認証モードを追加できます AWS CloudFormation。追加の認証モードの場合、 は、上記の値 (、、、AWS_LAMBDAAWS_IAMOPENID_CONNECT) API_KEYを取得する認証タイプ AWS AppSync を提供しますAMAZON_COGNITO_USER_POOLS

メインまたはデフォルトの承認タイプとしてAPI_KEYAWS_LAMBDA、または AWS_IAM を指定した場合、それを追加の承認モードの 1 つとして再び指定することはできません。同様に、追加の承認モード間で API_KEYAWS_LAMBDA、または AWS_IAM を重複して使用することはできません。複数の Amazon Cognito ユーザープールと OpenID Connect プロバイダーを使用できます。ただし、デフォルトの承認モードと追加の承認モード間で Amazon Cognito ユーザープールまたは OpenID Connect プロバイダーを重複して使用することはできません。Amazon Cognito ユーザープールまたは OpenID Connect プロバイダーに異なる複数のクライアントを設定する場合、対応する正規表現を使用できます。

API_KEY 認証

認証されていない には、認証された よりも厳密なスロットリングAPIsが必要ですAPIs。認証されていない GraphQL エンドポイントのスロットリングを制御する 1 つの方法は、 APIキーを使用することです。API キーは、認証されていない GraphQL エンドポイントを作成するときに AWS AppSync サービスによって生成される、アプリケーション内のハードコードされた値です。コンソール、、CLIまたはAWS AppSync APIリファレンス からAPIキーをローテーションできます。

Console
  1. にサインイン AWS Management Console し、AppSyncコンソール を開きます。

    1. APIs ダッシュボード で、GraphQL を選択しますAPI。

    2. サイドバー[設定] を選択します。

  2. デフォルト認証モード で、APIキー を選択します。

  3. API キーテーブルで、APIキーの追加 を選択します。

    テーブルに新しいAPIキーが生成されます。

    1. 古いAPIキーを削除するには、テーブルでAPIキーを選択し、削除を選択します

  4. ページの最下部で [保存] をクリックします。

CLI
  1. まだ設定していない場合は、 へのアクセスを設定します AWS CLI。詳細については、「設定の基本」を参照してください。

  2. update-graphql-api コマンドを実行して GraphQL API オブジェクトを作成します。

    この特定のコマンドには次の 2 つのパラメータを入力する必要があります。

    1. GraphQL api-idの API。

    2. name の新しい API。同じ name を使用できます。

    3. API_KEY となる authentication-type

    注記

    など、他のパラメータも設定Regionする必要がありますが、通常はデフォルト値になりますCLI。

    コマンドの例は、次のようになります。

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

    出力は で返されますCLI。の例を次に示します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" } }

API キーは最大 365 日間設定でき、既存の有効期限をその日から最大 365 日間延長できます。API キーは、開発目的またはパブリック を公開しても安全なユースケースに推奨されますAPI。

クライアントでは、APIキーはヘッダー によって指定されますx-api-key

たとえば、API_KEY'ABC123' である場合、次のように curl 経由で GraphQL クエリを送信できます。

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

AWS_LAMBDA 認証

AWS Lambda 関数を使用して独自のAPI認証ロジックを実装できます。プライマリオーソライザーまたはセカンダリオーソライザーのいずれかに Lambda 関数を使用できますが、 ごとに 1 つの Lambda 認証関数しか存在できない場合がありますAPI。Lambda 関数を認証に使用する場合、次のことが適用されます。

  • API で AWS_LAMBDAおよび AWS_IAM認証モードが有効になっている場合、SigV4 署名をAWS_LAMBDA認証トークンとして使用することはできません。

  • API で AWS_LAMBDAおよび OPENID_CONNECT認証モードまたは AMAZON_COGNITO_USER_POOLS 認証モードが有効になっている場合、OIDCトークンをAWS_LAMBDA認証トークンとして使用することはできません。OIDC トークンはベアラースキームである可能性があることに注意してください。

  • Lambda 関数は、リゾルバーに対して 5MB を超えるコンテキストデータを返してはいけません。

たとえば、認証トークン が 'ABC123' である場合、次のように curl 経由で GraphQL クエリを送信できます。

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

Lambda 関数は、各クエリまたはミューテーションの前に呼び出されます。戻り値は、APIID と認証トークンに基づいてキャッシュできます。デフォルトでは、キャッシュはオンになっていませんが、これは APIレベルで有効にすることも、関数の戻りttlOverride値に 値を設定することで有効にすることもできます。

必要に応じて、関数が呼び出される前に認証トークンを検証する正規表現を指定できます。これらの正規表現は、関数が呼び出される前に、認証トークンが正しい形式であることを検証するために使用されます。この正規表現と一致しないトークンを使用したリクエストは、自動的に拒否されます。

認証に使用される Lambda 関数には、 がそれらを AWS AppSync 呼び出すことができるように、 のプリンシパルポリシーappsync.amazonaws.comを適用する必要があります。このアクションは AWS AppSync コンソールで自動的に実行されます。 AWS AppSync コンソールはポリシーを削除しません。Lambda 関数にポリシーをアタッチする方法の詳細については、「 AWS Lambda デベロッパーガイド」の「リソースベースのポリシー」を参照してください。

指定した Lambda 関数は次の形状のイベントを受け取ります。

{ "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 } }

event オブジェクトには、アプリケーションクライアントから へのリクエストで送信されたヘッダーが含まれています AWS AppSync。

認証関数は少なくとも を返す必要があります。これはisAuthorized、リクエストが認証されているかどうかを示すブール値です。Lambda 認証関数から返される次のキー AWS AppSync を認識します。

isAuthorized (boolean、必須)

の値が GraphQL を呼び出すことをauthorizationToken許可されているかどうかを示すブール値API。

この値が true の場合、GraphQL の実行はAPI続行されます。この値が false の場合、UnauthorizedException が生成されます。

deniedFields (文字列のリスト、オプション)

リゾルバーから値が返された場合でも、そのリストは強制的に null に変更されます。

各項目は、 ARNの形式の完全修飾フィールドarn:aws:appsync:us-east-1:111122223333:apis/GraphQLApiId/types/TypeName/fields/FieldNameまたは の短い形式のいずれかですTypeName.FieldName。完全なARN形式は、2 つの が Lambda 関数オーソライザーAPIsを共有し、2 つの 間で共通のタイプとフィールドの間にあいまいさがある可能性がある場合に使用しますAPIs。

resolverContext (JSON オブジェクト、オプション)

リゾルバーテンプレート$ctx.identity.resolverContextで として表示されるJSONオブジェクト。たとえば、リゾルバーによって次の構造体が返されたとします。

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

リゾルバーテンプレート内の値 ctx.identity.resolverContext.apple は「very green」になります。resolverContext オブジェクト はキーと値のペアのみをサポートします。ネストされたキーはサポートされません。

警告

このJSONオブジェクトの合計サイズは 5MBを超えることはできません。

ttlOverride (integer、オプション)

応答をキャッシュする秒数。値が返されない場合は、 の値APIが使用されます。これが 0 の場合、応答はキャッシュされません。

Lambda オーソライザーのタイムアウトは 10 秒です。のパフォーマンスをスケーリングするために、できるだけ短い時間で実行する関数を設計することをお勧めしますAPI。

複数の AWS AppSync APIs が 1 つの認証 Lambda 関数を共有できます。クロスアカウントオーソライザーの使用は許可されていません。

複数の 間で認証関数を共有する場合APIs、短い形式のフィールド名 (typename.fieldname) が誤ってフィールドを非表示にする可能性があることに注意してください。でフィールドのあいまいさを解消するにはdeniedFields、 のARN形式であいまいなフィールドを指定できますarn:aws:appsync:region:accountId:apis/GraphQLApiId/types/typeName/fields/fieldName

AWS AppSyncで Lambda 関数をデフォルトの認証モードとして追加するには、

Console
  1. AWS AppSync コンソールにログインし、更新する API に移動します。

  2. の設定ページに移動しますAPI。

    APIレベル認証を に変更しますAWS Lambda

  3. API 呼び出しARNを承認する AWS リージョン と Lambda を選択します。

    注記

    適切なプリンシパルポリシーが自動的に追加され、 AWS AppSync Lambda 関数を呼び出します。

  4. 必要に応じて、レスポンスTTLとトークンの検証の正規表現を設定します。

AWS CLI
  1. 使用中の Lambda 関数に次のポリシーをアタッチします。

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

    関数のポリシーを単一の GraphQL にロックする場合はAPI、次のコマンドを実行できます。

    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. 特定の Lambda 関数をオーソライザーARNとして使用するように を更新します AWS AppSync API。

    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"
    注記

    トークンの正規表現など、他の設定オプションを含めることもできます。

次の例では、Lambda 関数が AWS AppSync 認証メカニズムとして使用されたとき、その Lambda 関数が持つさまざまな認証状態および認証失敗状態を示しています。

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 {}

SigV4 とOIDCトークン認証の制限を回避する

特定の認証モードが有効になっている場合、SigV4 署名またはOIDCトークンを Lambda 認証トークンとして使用できない問題を回避するために、次の方法を使用できます。

の で AWS_IAMおよび 認証モードが有効になっているときに、SigV4 AWS AppSync署名を Lambda AWS_LAMBDA認証トークンとして使用する場合はAPI、次の手順を実行します。

  • 新しい Lambda 認証トークンを作成するには、SigV4 署名にランダムなサフィックスおよび/またはプレフィックスを追加します。

  • 元の SigV4 署名を取得するには、Lambda 認証トークンからランダムなプレフィックスおよび/またはサフィックスを削除して、Lambda 関数を更新します。次に、元の SigV4 署名を認証に使用します。

の で認証モードまたは AMAZON_COGNITO_USER_POOLSおよび OPENID_CONNECT認証モードが有効になっているときに、OIDCトークンを Lambda AWS_LAMBDA認証トークンとして使用する場合は AWS AppSync API、次の手順を実行します。

  • 新しい Lambda 認証トークンを作成するには、OIDCトークンにランダムなサフィックスやプレフィックスを追加します。Lambda 認証トークンにはベアラースキームプレフィックスを含めないでください。

  • 元のOIDCトークンを取得するには、Lambda 認証トークンからランダムなプレフィックスやサフィックスを削除して Lambda 関数を更新します。次に、認証に元のOIDCトークンを使用します。

AWS_IAM 認証

この認証タイプは、AWS GraphQL の署名バージョン 4 の署名プロセスを強制しますAPI。 GraphQL Identity and Access Management (IAM) アクセスポリシーをこの認証タイプに関連付けることができます。アクセスキー (アクセスキー ID とシークレットアクセスキーで構成) または Amazon Cognito フェデレーティッドアイデンティティによって提供される有効期限の短い、一時的な認証情報を使用して、アプリケーションでこの関連付けを活用します。

すべてのデータオペレーションを実行できるアクセス権限を持つロールが必要な場合。

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

コンソールのメインAPIリストページYourGraphQLApiId AppSyncから、 の名前を直接確認できますAPI。または、 を使用して取得することもできますCLI。 aws appsync list-graphql-apis

特定の GraphQL オペレーションのみにアクセスを制限するには、ルートの QueryMutationSubscription の各フィールドに対してこれを実行します。

{ "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>" ] } ] }

たとえば、以下のスキーマがあり、すべての投稿を取得するアクセスを制限する場合。

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

ロールに対応するIAMポリシー (Amazon Cognito ID プールにアタッチできるポリシーなど) は次のようになります。

{ "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 認証

この認証タイプは、 OIDC準拠のサービスによって提供される OpenID 接続 (OIDC) トークンを適用します。アプリケーションは、OIDCプロバイダーによって定義されたユーザーと権限を活用してアクセスを制御できます。

発行者は、指定する唯一の必須設定値URLです AWS AppSync (例: https://auth.example.com)。これは、発行者HTTPS AWS AppSync /.well-known/openid-configurationに追加URLされ、OpenID Connect Discovery 仕様https://auth.example.com/.well-known/openid-configurationに従って で OpenID 設定を見つけることでアドレス指定できるURL必要があります。 OpenID この では、RFC5785準拠JSONドキュメントを取得する必要がありますURL。このJSONドキュメントには、署名jwks_uriキーを持つJSONウェブキーセット (JWKS) ドキュメントを指すキーが含まれている必要があります。 AWS AppSync には ktyおよび のJSONフィールドJWKSが含まれている必要がありますkid

AWS AppSync は、さまざまな署名アルゴリズムをサポートしています。

署名アルゴリズム
RS256
RS384
RS512
PS256
PS384
PS512
HS256
HS384
HS512
ES256
ES384
ES512

RSA アルゴリズムを使用することをお勧めします。プロバイダーによって発行されたトークンに、トークンが発行された時刻 (iat) が含まれている必要があり、認証された時刻 (auth_time) が含まれる場合があります。OpenID Connect 設定で発行時刻 (iatTTL) と認証時刻 (authTTL) TTLの値を指定して、追加の検証を行うことができます。使用するプロバイダーが複数のアプリケーションを認証している場合は、クライアント ID で認証するために使用される正規表現を (clientId) も入力できます。clientId が OpenID Connect 設定に存在する場合、 は、 clientIdをトークン内の audまたは クレームのいずれかと一致させることで、 azp クレーム AWS AppSync を検証します。

複数のクライアントを検証するには、正規表現の「または」であるパイプライン演算子 (「|」) IDsを使用します。例えば、OIDCアプリケーションに 0A1S2D、1F4G9H、1J6L4B、6 IDsなどのクライアントを持つ 4 つのクライアントがありGS5MG、最初の 3 つのクライアント のみを検証する場合IDs、クライアント ID フィールドに 1F4G9H |1J6L4B|6GS5MG を配置します。 0A1S2D, 1F4G9H, 1J6L4B

AMAZON_COGNITO_USER_POOLS 認証

この認証タイプは、Amazon Cognito ユーザープールによって提供されるOIDCトークンを適用します。アプリケーションは、別のアカウントのユーザープールとユーザープールの両方のユーザーとグループを活用し AWS 、これらを GraphQL フィールドに関連付けてアクセスを制御できます。

Amazon Cognito ユーザープールを使用する場合、ユーザーが属するグループを作成できます。この情報は、GraphQL オペレーションを送信するときにアプリケーションが認証ヘッダー AWS AppSync で に送信するJWTトークンにエンコードされます。スキーマで GraphQL ディレクティブを使用して、フィールドでどのグループがどのリゾルバーを起動できるのかを制御します。したがってカスタマーのアクセスを細かく制御できます。

たとえば、以下の GraphQL スキーマがあるとします。

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

Amazon Cognito ユーザープールに 2 つのグループ (bloggers と readers) があり、readers が新しいエントリを追加できないように制限する場合、スキーマは次のようになります。

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"]) } ...

アクセスに関する特定の grant-or-deny 戦略をデフォルトにする場合は、 @aws_auth ディレクティブを省略できます。GraphQL を作成するときに、コンソールまたは次のCLIコマンドAPIを使用して、ユーザープール設定で grant-or-deny 戦略を指定できます。

$ 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"}'

追加の承認モードの使用

追加の認証モードを追加すると、 AWS AppSync GraphQL APIレベル (GraphqlApiオブジェクトで直接設定できる authenticationType フィールド) で認証設定を直接設定でき、スキーマのデフォルトとして機能します。つまり、特定のディレクティブを持たないタイプは、APIレベル認証設定に合格する必要があります。

スキーマレベルでは、スキーマでディレクティブを使用して追加の承認モードを指定できます。スキーマの個々のフィールドに承認モードを指定できます。たとえば、API_KEY 承認の場合、スキーマオブジェクトタイプの定義/フィールドで @aws_api_key を使用します。以下のディレクティブは、スキーマフィールドおよびオブジェクトタイプ定義でサポートされています。

  • @aws_api_key - フィールドが API_KEY で承認されることを指定します。

  • @aws_iam - フィールドが AWS_IAM で承認されることを指定します。

  • @aws_oidc - フィールドが OPENID_CONNECT で承認されることを指定します。

  • @aws_cognito_user_pools - フィールドが AMAZON_COGNITO_USER_POOLS で承認されることを指定します。

  • @aws_lambda - フィールドが AWS_LAMBDA で承認されることを指定します。

@aws_auth ディレクティブを追加の承認モードと共に使用することはできません。@aws_auth は、追加の承認モードのない AMAZON_COGNITO_USER_POOLS 承認のコンテキストでのみ機能します。ただし、同じ引数で @aws_auth ディレクティブの代わりに @aws_cognito_user_pools ディレクティブを使用できます。2 つの主な違いは、フィールドとオブジェクトタイプの定義で @aws_cognito_user_pools を指定できることです。

追加の承認モードがどのように機能し、スキーマでどのように指定できるかを理解するために、以下のスキーマを見てみましょう。

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! } ...

このスキーマでは、 AWS_IAMが AWS AppSync GraphQL のデフォルトの認証タイプであると仮定しますAPI。つまり、ディレクティブのないフィールドは AWS_IAM を使用して保護されます。たとえば、Query タイプの getPost フィールドの場合です。スキーマディレクティブにより、複数の承認モードを使用できます。例えば、 を AWS AppSync GraphQL の追加認証モードとしてAPI_KEY設定しAPI、 @aws_api_key ディレクティブ (getAllPostsこの例では など) を使用してフィールドをマークできます。ディレクティブはフィールドレベルで機能するため、Post タイプへの API_KEY アクセスも許可する必要があります。そのためには、Post タイプの各フィールドをディレクティブでマークするか、Post タイプを @aws_api_key ディレクティブでマークします。

Post タイプのフィールドへのアクセスをさらに制限するには、以下に示すように、Post タイプの個々のフィールドに対してディレクティブを使用できます。

たとえば、restrictedContent フィールドを Post タイプに追加し、@aws_iam ディレクティブを使用してそのフィールドへのアクセスを制限できます。ただし restrictedContent に、AWS_IAM 認証済みリクエストからはアクセスできますが、API_KEY リクエストからはアクセスできません。

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 } ...

きめ細かなアクセスコントロール

前述の情報は、特定の GraphQL フィールドへのアクセスを制限または許可する方法を示しています。特定の条件に基づいて (たとえば、呼び出し元のユーザーがだれであるかや、そのユーザーがデータを所有しているかどうかに基づいて) データに対するアクセスコントロールを設定する場合は、リゾルバーでマッピングテンプレートを使用できます。より複雑なビジネスロジックも実行できます。「フィルタ処理情報」で説明します。

このセクションでは、DynamoDB リゾルバーマッピングテンプレート使用してデータのアクセスコントロールを設定する方法を示します。

先に進む前に、 のマッピングテンプレートに慣れていない場合は AWS AppSync、DynamoDB の「リゾルバーマッピングテンプレートリファレンス」と「リゾルバーマッピングテンプレートリファレンス」を確認してください。 DynamoDB

DynamoDB を使用した次の例では、前述のブログ投稿スキーマを使用し、投稿を作成したユーザーのみが編集を許可されているものとします。評価プロセスは、Amazon Cognito ユーザープールなどを使用して、ユーザーがアプリケーションで認証情報を取得し、GraphQL オペレーションの一部として、これらの認証情報を渡すというものです。その後、マッピングテンプレートが、条件ステートメントで、認証情報 (username など) からの値を置き換えます。値はデータベースの値と比較されます。

この機能を追加するには、次のように editPost GraphQL フィールドを追加します。

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! } ...

editPost のリゾルバーマッピングテンプレート (このセクションの最後にある例) では、投稿を作成したユーザーのみが編集を許可されるように、データストアに対する論理チェックを実行する必要があります。これは編集オペレーションなので、DynamoDB の UpdateItem に対応します。ユーザー ID 検証に渡されるコンテキストを使用して、このアクションを実行する前に条件チェックを実行できます。これは次の値を持つ Identity オブジェクトに保存されます。

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

DynamoDB UpdateItem コールでこのオブジェクトを使用するには、比較用テーブルにユーザー ID 情報を保存する必要があります。まず、addPost ミューテーションは作成者を保存する必要があります。次に、更新する前に、editPost ミューテーションで条件チェックを実行する必要があります。

Author 列としてユーザー ID を保存する addPost のリゾルバーコードの例を次に示します。

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;

Author 属性が、アプリケーションから得られた Identity オブジェクトから入力されていることに注意してください。

最後に、editPost のリゾルバーコードの例を次に示します。これは、投稿を作成したユーザーからリクエストが来た場合にのみ、ブログ投稿のコンテンツを更新します。

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;

この例では、UpdateItem ではなく、すべての値を上書きする PutItem を使用していますが、condition ステートメントブロックには同じ概念が適用されます。

フィルタ処理情報

データソースからのレスポンスを制御できないときに、データソースへの正常な書き込みまたは読み取りに対して、不必要な情報をクライアントに送信したくない場合があります。このような場合は、レスポンスマッピングテンプレートを使用して情報をフィルタリングすることができます。

たとえば、ブログ投稿 DynamoDB テーブルに適切なインデックス (Author のインデックスなど) がない場合を考えます。以下のリゾルバーを使用できます。

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; }

リクエストハンドラは、呼び出し元が投稿の作成者でなくても、項目をフェッチします。これによってすべてのデータが返されるのを防ぐために、レスポンスハンドラは呼び出し元が項目の作成者と一致することを確認します。発信者がこのチェックに一致しない場合に、null レスポンスのみが返されます。

データソースへのアクセス

AWS AppSync は Identity and Access Management (IAM) ロールとアクセスポリシーを使用してデータソースと通信します。既存のロールを使用している場合、 がロールを引き AWS AppSync 受けるには、信頼ポリシーを追加する必要があります。信頼関係は以下のようになります。

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

必要な最小限のリソースについて作業を行うアクセス許可のみを持つように、ロールのアクセスポリシーを制限することが重要です。 AppSync コンソールを使用してデータソースを作成し、ロールを作成すると、自動的に実行されます。ただし、IAMコンソールから組み込みサンプルテンプレートを使用してコンソールの AWS AppSync外部でロールを作成する場合、アクセス許可はリソースに自動的にスコープダウンされないため、アプリケーションを本番環境に移行する前にこのアクションを実行する必要があります。