

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

# GraphQL API を保護するための認可と認証の設定
<a name="security-authz"></a>

AWS AppSync は、GraphQL APIs を保護するため、API キー、Lambda、IAM、OpenID Connect、および Cognito ユーザープールの認可タイプを提供します。各オプションは、異なるセキュリティ方法を提供します。

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

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

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

1. **OpenID Connect 認可**: ユーザー認証のために OIDC 準拠のサービスと統合します。

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

## 認可タイプ
<a name="authorization-types"></a>

 AWS AppSync GraphQL API を操作するためにアプリケーションを認可するには、5 つの方法があります。 AWS AppSync API または CLI コールで次のいずれかの認可タイプ値を指定することで、使用する認可タイプを指定します。
+   
** `API_KEY` **  
API キーを使用する場合。
+   
** `AWS_LAMBDA` **  
 AWS Lambda 関数を使用する場合。
+   
** `AWS_IAM` **  
 AWS Identity and Access Management ([IAM](https://aws.amazon.com/iam/)) アクセス許可を使用する場合。
+   
** `OPENID_CONNECT` **  
OpenID Connect プロバイダーを使用する場合。
+   
** `AMAZON_COGNITO_USER_POOLS` **  
Amazon Cognito ユーザープールを使用する場合。

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

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

API 設定に変更を保存すると、 は変更の伝達 AWS AppSync を開始します。設定変更が反映されるまで、 は AWS AppSync 引き続き以前の設定のコンテンツを提供します。設定変更が反映されると、 AWS AppSync はすぐに新しい設定に基づいてコンテンツの提供を開始します。 AWS AppSync が API の変更を伝達している間、API が以前の設定または新しい設定に基づいてコンテンツを提供しているかどうかを判断できません。

## API\_KEY 認可
<a name="api-key-authorization"></a>

認証されていない API は、認証された API よりも厳格なスロットリングが必要になります。認証されていない GraphQL エンドポイントに対してスロットリングを制御する方法の 1 つは API キーを使用します。API キーは、認証されていない GraphQL エンドポイントを作成するときに AWS AppSync サービスによって生成されるアプリケーション内のハードコードされた値です。コンソール、CLI、または [AWS AppSync API リファレンス](https://docs.aws.amazon.com/appsync/latest/APIReference/)から API キーを更新できます。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

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

1. **[API キー]** テーブルで、**[API キーの追加]** を選択します。

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

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

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

------
#### [ CLI ]

1. まだ設定していない場合は、 CLI AWS へのアクセスを設定します。詳細については、「[設定の基本](https://docs.aws.amazon.com//cli/latest/userguide/cli-configure-quickstart.html)」を参照してください。

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-graphql-api.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-graphql-api.html) コマンドを実行して GraphQL API オブジェクトを作成します。

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

   1. GraphQL API の `api-id`。

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

   1. `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 認可
<a name="aws-lambda-authorization"></a>

 AWS Lambda 機能を使用して、独自の API 認可ロジックを実装できます。Lambda 関数をプライマリオーソライザーまたはセカンダリオーソライザーに使用できますが、API ごとに Lambda 認可関数は 1 つしかありません。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 関数は、各クエリまたはミューテーションの前に呼び出されます。戻り値は API ID と認証トークンに基づいてキャッシュできます。Lambda オーソライザーのレスポンスが 1,048,576 バイト未満の場合、 AWS AppSync は後続のリクエストのレスポンスをキャッシュします。Lambda オーソライザーのレスポンスが 1,048,576 バイト以上の場合、 AWS AppSync はレスポンスをキャッシュせず、受信リクエストごとに Lambda オーソライザーを呼び出します。パフォーマンスを最適化し、Lambda 呼び出しコストを最小限に抑えるには、Lambda オーソライザーのレスポンスを 1,048,576 バイトに制限することをお勧めします。デフォルトでは、キャッシュは有効になっていませんが、これは API レベルで、または関数の戻り値の `ttlOverride` の値を設定することで有効にすることができます。

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

認可に使用される Lambda 関数には、 `appsync.amazonaws.com` がそれらを AWS AppSync 呼び出すことができるように、 のプリンシパルポリシーを適用する必要があります。このアクションは AWS AppSync コンソールで自動的に行われます。 AWS AppSync コンソールはポリシーを削除*しません*。Lambda 関数へのポリシーのアタッチの詳細については、「 AWS Lambda デベロッパーガイド」の[「リソースベースのポリシー](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke)」を参照してください。

指定した 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 を認識します。

**注記**  
WebSocket 接続オペレーション`requestContext`の `operationName`の の値は、 によって`DeepDish:Connect` AWS AppSync 「」に設定されます。

### 関数のリスト
<a name="aws-lambda-authorization-list"></a>

`isAuthorized` (boolean、必須)  
GraphQL API への呼び出しをおこなうために `authorizationToken` の値が認証されるかどうかを示すブール値。  
この値が true の場合、GraphQL API の実行が継続されます。この値が false の場合、`UnauthorizedException` が生成されます。

`deniedFields` (文字列のリスト、オプション)  
リゾルバーから値が返された場合でも、そのリストは強制的に `null` に変更されます。  
各項目は、`arn:aws:appsync:{{us-east-1}}:{{111122223333}}:apis/{{GraphQLApiId}}/types/{{TypeName}}/fields/{{FieldName}}` の形式、または `{{TypeName}}.{{FieldName}}` の短い形式の完全修飾フィールド ARN です。2 つの API が Lambda 関数のオーソライザーを共有し、2 つの API の間に共通の型とフィールドの間にあいまいさがある可能性がある場合は、完全な ARN 形式を使用する必要があります。

`resolverContext` (JSON オブジェクト、オプション)  
リゾルバーテンプレート内の `$ctx.identity.resolverContext` として可視化されるJSON オブジェクト。たとえば、リゾルバーによって次の構造体が返されたとします。  

```
{
  "isAuthorized":true
  "resolverContext": {
    "banana":"very yellow",
    "apple":"very green" 
  }
}
```
リゾルバーテンプレート内の値 `ctx.identity.resolverContext.apple` は「`very green`」になります。`resolverContext` オブジェクト はキーと値のペアのみをサポートします。ネストされたキーはサポートされません。  
この JSON オブジェクトの合計サイズは 5 MB を超えないようにしてください。

`ttlOverride` (integer、オプション)  
応答をキャッシュする秒数。値が返されない場合は、API からの値が使用されます。これが 0 の場合、応答はキャッシュされません。

Lambda オーソライザーの標準タイムアウトは 10 秒ですが、ピークトラフィック条件下ではより早くタイムアウトすることがあります。API のパフォーマンスをスケーリングするために、できるだけ短い時間 (1 秒未満) で実行する関数を設計することをお勧めします。

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

複数の API 間で認可関数を共有する場合は、短い形式のフィールド名 (`{{typename}}.{{fieldname}}`) が誤ってフィールドを隠すことがあります。`deniedFields` のフィールドを明確化するには、明確なフィールド ARN を `arn:aws:appsync:{{region}}:{{accountId}}:apis/{{GraphQLApiId}}/types/{{typeName}}/fields/{{fieldName}}` の形式で指定できます。

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

------
#### [ Console ]

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

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

   API レベルの認可を**AWS Lambda**に変更します。

1. API コールを承認する AWS リージョン と Lambda ARN を選択します。
**注記**  
適切なプリンシパルポリシーが自動的に追加され、 AWS AppSync Lambda 関数を呼び出します。

1. 必要に応じて、レスポンス 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
   ```

1. 指定された 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 トークンの認可制限を回避する
<a name="aws-lambda-authorization-create-new-auth-token"></a>

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

 AWS AppSyncの API に対して `AWS_IAM` および `AWS_LAMBDA` 認可モードが有効になっているとき、SigV4 署名を Lambda 認可トークンとして使用する場合は、次の操作を行います。
+ 新しい Lambda 認可トークンを作成するには、SigV4 署名にランダムなサフィックスおよび/またはプレフィックスを追加します。
+ 元の SigV4 署名を取得するには、Lambda 認可トークンからランダムなプレフィックスおよび/またはサフィックスを削除して、Lambda 関数を更新します。次に、元の SigV4 署名を認証に使用します。

認可モードまたは `AMAZON_COGNITO_USER_POOLS`および `OPENID_CONNECT`認可モードが の API に対して有効になっているときに、OIDC トークンを Lambda AWS AppSync`AWS_LAMBDA`認可トークンとして使用する場合は、以下を実行します。
+ 新しい Lambda 認可トークンを作成するには、OIDC トークンにランダムなサフィックスおよび/またはプレフィックスを追加します。Lambda 認可トークンにはベアラースキームプレフィックスを含めないでください。
+ 元の OIDC トークンを取得するには、Lambda 認可トークンからランダムなプレフィックスおよび/またはサフィックスを削除して、Lambda 関数を更新します。次に、元の OIDC トークンを認証に使用します。

## AWS\_IAM 認可
<a name="aws-iam-authorization"></a>

この承認タイプでは、GraphQL API に対して [AWS 署名バージョン 4 署名プロセス](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)を使用する必要があります。Identity and Access Management ([IAM](https://aws.amazon.com/iam/)) アクセスポリシーをこの承認タイプに関連付けることができます。アクセスキー (アクセスキー ID とシークレットアクセスキーで構成) または Amazon Cognito フェデレーティッドアイデンティティによって提供される有効期限の短い、一時的な認証情報を使用して、アプリケーションでこの関連付けを活用します。

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

------
#### [ JSON ]

****  

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

------

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

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

------
#### [ JSON ]

****  

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

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

------
#### [ JSON ]

****  

```
{
    "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 認可
<a name="openid-connect-authorization"></a>

この認可タイプは、OIDC 準拠サービスによって提供される [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html) (OIDC) トークンを適用します。アプリケーションは、アクセス制御に対して、使用する OIDC プロバイダーによって定義されたユーザーと権限を活用できます。

発行者 URL は、 AWS AppSync に提供する唯一の必須設定値です (例: `https://auth.example.com`)。この URL は HTTPS 経由でアドレス可能である必要があります。 AWS AppSync は発行者 URL `/.well-known/openid-configuration` に を追加し、OpenID Connect Discovery 仕様`https://auth.example.com/.well-known/openid-configuration`に従って で OpenID 設定を見つけます。 [OpenID ](https://openid.net/specs/openid-connect-discovery-1_0.html) この URL で [RFC5785](https://tools.ietf.org/html/rfc5785) 準拠の JSON ドキュメントを取得するものとします。この JSON ドキュメントには、署名`jwks_uri`キーを含む JSON Web Key Set (JWKS) ドキュメントを指すキーが含まれている必要があります。 AWS AppSync では、JWKS に `kty`および の JSON フィールドが含まれている必要があります`kid`。

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


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

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

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

API が複数の認可タイプで設定されている場合、 AWS AppSync はリクエストヘッダーから JWT トークンに存在する発行者 (iss claim) を API 設定で指定された発行者 URL と比較することで検証します。ただし、API が OPENID\_CONNECT 認可のみを使用して設定されている場合、 AWS AppSync はこの発行者 URL 検証ステップをスキップします。

## AMAZON\_COGNITO\_USER\_POOLS 認可
<a name="amazon-cognito-user-pools-authorization"></a>

この認可タイプでは、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"])
}
...
```

`@aws_auth` ディレクティブは、個別のアクセス許可/拒否戦略をデフォルトにする場合に省略できることに注意してください。コンソールまたは以下の CLI コマンド経由で GraphQL API を作成するときに、ユーザープール設定で許可/拒否戦略を指定できます。

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

## 追加の承認モードの使用
<a name="using-additional-authorization-modes"></a>

追加の認可モードを追加すると、 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 で を追加の認可モードとして`API_KEY`設定し、 `@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
}
...
```

## きめ細かなアクセスコントロール
<a name="fine-grained-access-control"></a>

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

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

さらに進む前に、 AWS AppSync のマッピングテンプレートがよくわからない場合は、「[リゾルバーのマッピングテンプレートリファレンス](resolver-mapping-template-reference.md#aws-appsync-resolver-mapping-template-reference)」と「[DynamoDB のリゾルバーのマッピングテンプレートリファレンス](resolver-mapping-template-reference-dynamodb.md#aws-appsync-resolver-mapping-template-reference-dynamodb)」を参照してください。

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

![トークンの取得、リクエストの送信、条件付きチェック、オペレーションの実行を示す 4 ステップのワークフロー。](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/FGAC.png)


この機能を追加するには、次のように `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` ステートメントブロックには同じ概念が適用されます。

## フィルタ処理情報
<a name="aws-appsync-filtering-information"></a>

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

たとえば、ブログ投稿 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 レスポンスのみが返されます。

## データソースへのアクセス
<a name="data-source-access"></a>

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

------
#### [ JSON ]

****  

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

------

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