

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Mengkonfigurasi otorisasi dan otentikasi untuk mengamankan GraphQL Anda APIs
<a name="security-authz"></a>

AWS AppSync menawarkan jenis otorisasi berikut untuk mengamankan APIs GraphQL: kunci API, Lambda, IAM, OpenID Connect, dan Cognito User Pools. Setiap opsi menyediakan metode keamanan yang berbeda: 

1. **Otorisasi Kunci API**: Mengontrol pembatasan untuk tidak diautentikasi APIs, memberikan opsi keamanan sederhana. 

1. **Otorisasi Lambda**: Mengaktifkan logika otorisasi khusus, menjelaskan input dan output fungsi secara rinci. 

1. **Otorisasi IAM**: Memanfaatkan AWS proses penandatanganan versi 4 tanda tangan, memungkinkan kontrol akses berbutir halus melalui kebijakan IAM. 

1. **Otorisasi OpenID Connect**: Terintegrasi dengan layanan yang sesuai dengan OIDC untuk otentikasi pengguna. 

1. **Cognito User Pools**: Menerapkan kontrol akses berbasis grup menggunakan fitur manajemen pengguna Cognito. 

## Jenis otorisasi
<a name="authorization-types"></a>

Ada lima cara Anda dapat mengotorisasi aplikasi untuk berinteraksi dengan AWS AppSync GraphQL API Anda. Anda menentukan jenis otorisasi yang Anda gunakan dengan menentukan salah satu nilai jenis otorisasi berikut dalam panggilan API AWS AppSync atau CLI Anda:
+   
** `API_KEY` **  
Untuk menggunakan kunci API.
+   
** `AWS_LAMBDA` **  
Untuk menggunakan suatu AWS Lambda fungsi.
+   
** `AWS_IAM` **  
Untuk menggunakan izin AWS Identity and Access Management ([IAM](https://aws.amazon.com/iam/)).
+   
** `OPENID_CONNECT` **  
Untuk menggunakan penyedia OpenID Connect Anda.
+   
** `AMAZON_COGNITO_USER_POOLS` **  
Untuk menggunakan kumpulan pengguna Amazon Cognito.

Jenis otorisasi dasar ini berfungsi untuk sebagian besar pengembang. Untuk kasus penggunaan yang lebih lanjut, Anda dapat menambahkan mode otorisasi tambahan melalui konsol, CLI, dan. AWS CloudFormation Untuk mode otorisasi tambahan, AWS AppSync berikan jenis otorisasi yang mengambil nilai yang tercantum di atas (yaitu,,`API_KEY`, `AWS_LAMBDA` `AWS_IAM``OPENID_CONNECT`, dan`AMAZON_COGNITO_USER_POOLS`).

Saat Anda menentukan`API_KEY`,`AWS_LAMBDA`, atau `AWS_IAM` sebagai jenis otorisasi utama atau default, Anda tidak dapat menentukannya lagi sebagai salah satu mode otorisasi tambahan. Demikian pula, Anda tidak dapat menduplikasi`API_KEY`, `AWS_LAMBDA` atau `AWS_IAM` di dalam mode otorisasi tambahan. Anda dapat menggunakan beberapa Amazon Cognito User Pools dan penyedia OpenID Connect. Namun, Anda tidak dapat menggunakan duplikat Amazon Cognito User Pools atau penyedia OpenID Connect antara mode otorisasi default dan salah satu mode otorisasi tambahan. Anda dapat menentukan klien yang berbeda untuk Kumpulan Pengguna Amazon Cognito atau penyedia OpenID Connect menggunakan ekspresi reguler konfigurasi yang sesuai.

Saat Anda menyimpan perubahan pada konfigurasi API Anda, AWS AppSync mulailah menyebarkan perubahan. Sampai perubahan konfigurasi Anda disebarkan, AWS AppSync terus layani konten Anda dari konfigurasi sebelumnya. Setelah perubahan konfigurasi Anda disebarkan, AWS AppSync segera mulai menyajikan konten Anda berdasarkan konfigurasi baru. Saat AWS AppSync menyebarkan perubahan Anda untuk API, kami tidak dapat menentukan apakah API menyajikan konten Anda berdasarkan konfigurasi sebelumnya atau konfigurasi baru.

## API\$1KEY otorisasi
<a name="api-key-authorization"></a>

Tidak diautentikasi APIs membutuhkan pembatasan yang lebih ketat daripada yang diautentikasi. APIs Salah satu cara untuk mengontrol pelambatan untuk titik akhir GraphQL yang tidak diautentikasi adalah melalui penggunaan kunci API. Kunci API adalah nilai hard-code dalam aplikasi Anda yang dihasilkan oleh AWS AppSync layanan saat Anda membuat titik akhir GraphQL yang tidak diautentikasi. Anda dapat memutar kunci API dari konsol, dari CLI, atau dari referensi [AWS AppSync API](https://docs.aws.amazon.com/appsync/latest/APIReference/).

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

1. Masuk ke Konsol Manajemen AWS dan buka [AppSync konsol](https://console.aws.amazon.com/appsync/).

   1. Di **APIs dasbor**, pilih GraphQL API Anda.

   1. Di **Sidebar**, pilih **Pengaturan**.

1. Di bawah **mode otorisasi default**, pilih **kunci API**.

1. Dalam tabel **kunci API**, pilih **Tambahkan kunci API**.

   Kunci API baru akan dihasilkan dalam tabel.

   1. Untuk menghapus kunci API lama, pilih kunci API di tabel lalu pilih **Hapus**.

1. Pilih **Simpan** di bagian bawah halaman.

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

1. Jika Anda belum melakukannya, konfigurasikan akses Anda ke AWS CLI. Untuk informasi selengkapnya, lihat [Dasar-dasar konfigurasi](https://docs.aws.amazon.com//cli/latest/userguide/cli-configure-quickstart.html).

1. Buat objek GraphQL API dengan menjalankan perintah. [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)

   Anda harus mengetikkan dua parameter untuk perintah khusus ini:

   1. `api-id`Dari GraphQL API Anda.

   1. Yang baru `name` dari API Anda. Anda dapat menggunakan hal yang sama`name`.

   1. Itu`authentication-type`, yang akan menjadi`API_KEY`.
**catatan**  
Ada parameter lain seperti `Region` yang harus dikonfigurasi tetapi biasanya akan default ke nilai konfigurasi CLI Anda.

   Contoh perintah mungkin terlihat seperti ini:

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

   Output akan dikembalikan dalam CLI. Berikut adalah contoh di 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"
       }
   }
   ```

------

Kunci API dapat dikonfigurasi hingga 365 hari, dan Anda dapat memperpanjang tanggal kedaluwarsa yang ada hingga 365 hari lagi sejak hari itu. Kunci API direkomendasikan untuk tujuan pengembangan atau kasus penggunaan di mana aman untuk mengekspos API publik.

Pada klien, kunci API ditentukan oleh header`x-api-key`.

Misalnya, jika ya`'ABC123'`, Anda `API_KEY` dapat mengirim kueri `curl` GraphQL melalui sebagai berikut:

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

## AWS\$1LAMBDA otorisasi
<a name="aws-lambda-authorization"></a>

Anda dapat menerapkan logika otorisasi API Anda sendiri menggunakan AWS Lambda fungsi. Anda dapat menggunakan fungsi Lambda untuk otorisasi primer atau sekunder, tetapi mungkin hanya ada satu fungsi otorisasi Lambda per API. Saat menggunakan fungsi Lambda untuk otorisasi, berikut ini berlaku:
+ Jika API mengaktifkan mode `AWS_IAM` otorisasi `AWS_LAMBDA` dan, tanda tangan SigV4 tidak dapat digunakan sebagai token otorisasi. `AWS_LAMBDA`
+ Jika API memiliki mode `AWS_LAMBDA` dan `OPENID_CONNECT` otorisasi atau mode `AMAZON_COGNITO_USER_POOLS` otorisasi diaktifkan, maka token OIDC tidak dapat digunakan sebagai token otorisasi. `AWS_LAMBDA` Perhatikan bahwa token OIDC dapat menjadi skema Pembawa.
+ Fungsi Lambda tidak boleh mengembalikan lebih dari 5MB data kontekstual untuk resolver.

Misalnya, jika token otorisasi Anda`'ABC123'`, Anda dapat mengirim kueri GraphQL melalui curl sebagai berikut: 

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

Fungsi Lambda dipanggil sebelum setiap kueri atau mutasi. Nilai pengembalian dapat di-cache berdasarkan ID API dan token otentikasi. Ketika respons otorisasi Lambda kurang dari 1.048.576 byte, cache respons untuk permintaan berikutnya. AWS AppSync Jika respons otorisasi Lambda sama dengan atau lebih besar dari 1.048.576 byte, respons AWS AppSync tidak di-cache dan memanggil otorisasi Lambda untuk setiap permintaan yang masuk. Untuk mengoptimalkan kinerja dan meminimalkan biaya pemanggilan Lambda, sebaiknya Anda membatasi respons otorisasi Lambda hingga 1.048.576 byte. Secara default, caching tidak diaktifkan, tetapi ini dapat diaktifkan pada tingkat API atau dengan menetapkan `ttlOverride` nilai dalam nilai pengembalian fungsi. 

Ekspresi reguler yang memvalidasi token otorisasi sebelum fungsi dipanggil dapat ditentukan jika diinginkan. Ekspresi reguler ini digunakan untuk memvalidasi bahwa token otorisasi memiliki format yang benar sebelum fungsi Anda dipanggil. Setiap permintaan menggunakan token yang tidak cocok dengan ekspresi reguler ini akan ditolak secara otomatis. 

Fungsi Lambda yang digunakan untuk otorisasi memerlukan kebijakan utama `appsync.amazonaws.com` untuk diterapkan pada mereka untuk memungkinkan AWS AppSync untuk memanggil mereka. Tindakan ini dilakukan secara otomatis di AWS AppSync konsol; AWS AppSync Konsol *tidak* menghapus kebijakan. Untuk informasi selengkapnya tentang melampirkan kebijakan ke fungsi Lambda, [lihat Kebijakan berbasis sumber daya di Panduan Pengembang](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html#permissions-resource-serviceinvoke). AWS Lambda 

Fungsi Lambda yang Anda tentukan akan menerima acara dengan bentuk berikut:

```
{
    "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`Objek berisi header yang dikirim dalam permintaan dari klien aplikasi ke AWS AppSync.

Fungsi otorisasi harus mengembalikan setidaknya`isAuthorized`, boolean yang menunjukkan jika permintaan diotorisasi. AWS AppSync mengenali kunci berikut yang dikembalikan dari fungsi otorisasi Lambda:

**catatan**  
Nilai untuk operasi `operationName` in `requestContext` for a WebSocket connect diatur oleh AWS AppSync ke "`DeepDish:Connect`”.

### Daftar fungsi
<a name="aws-lambda-authorization-list"></a>

`isAuthorized`(boolean, diperlukan)  
Nilai boolean yang menunjukkan apakah nilai di `authorizationToken` diotorisasi untuk melakukan panggilan ke GraphQL API.  
Jika nilai ini benar, eksekusi GraphQL API berlanjut. Jika nilai ini salah, an `UnauthorizedException` dinaikkan

`deniedFields`(daftar string, opsional)  
Daftar yang secara paksa diubah menjadi`null`, bahkan jika nilai dikembalikan dari resolver.  
Setiap item adalah bidang ARN yang memenuhi syarat penuh dalam bentuk `arn:aws:appsync:us-east-1:111122223333:apis/GraphQLApiId/types/TypeName/fields/FieldName` atau bentuk pendek. `TypeName.FieldName` Formulir ARN lengkap harus digunakan ketika dua APIs berbagi otorisasi fungsi Lambda dan mungkin ada ambiguitas antara tipe dan bidang umum di antara keduanya. APIs

`resolverContext`(Objek JSON, opsional)  
Sebuah objek JSON terlihat seperti `$ctx.identity.resolverContext` pada template resolver. Misalnya, jika struktur berikut dikembalikan oleh resolver:  

```
{
  "isAuthorized":true
  "resolverContext": {
    "banana":"very yellow",
    "apple":"very green" 
  }
}
```
Nilai `ctx.identity.resolverContext.apple` dalam template resolver akan menjadi "”`very green`. `resolverContext`Objek hanya mendukung pasangan kunci-nilai. Kunci bersarang tidak didukung.  
Ukuran total objek JSON ini tidak boleh melebihi 5MB.

`ttlOverride`(bilangan bulat, opsional)  
Jumlah detik respons harus di-cache. Jika tidak ada nilai yang dikembalikan, nilai dari API akan digunakan. Jika ini 0, responsnya tidak di-cache.

Otorisasi Lambda memiliki batas waktu standar 10 detik tetapi mungkin time out lebih awal dalam kondisi lalu lintas puncak. Kami merekomendasikan merancang fungsi untuk dijalankan dalam waktu sesingkat mungkin (di bawah 1 d) untuk menskalakan kinerja API Anda.

Beberapa AWS AppSync APIs dapat berbagi fungsi Lambda otentikasi tunggal. Penggunaan otorisasi lintas akun tidak diizinkan.

Saat berbagi fungsi otorisasi di antara beberapa APIs, ketahuilah bahwa nama bidang bentuk pendek (`typename.fieldname`) mungkin secara tidak sengaja menyembunyikan bidang. Untuk membedakan bidang di`deniedFields`, Anda dapat menentukan bidang ARN yang tidak ambigu dalam bentuk. `arn:aws:appsync:region:accountId:apis/GraphQLApiId/types/typeName/fields/fieldName` 

Untuk menambahkan fungsi Lambda sebagai mode otorisasi default di: AWS AppSync

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

1. Masuk ke AWS AppSync Konsol dan navigasikan ke API yang ingin Anda perbarui.

1. Arahkan ke halaman Pengaturan untuk API Anda.

   Ubah otorisasi tingkat API menjadi. **AWS Lambda**

1. Pilih Wilayah AWS dan Lambda ARN untuk mengotorisasi panggilan API terhadap.
**catatan**  
Kebijakan utama yang sesuai akan ditambahkan secara otomatis, memungkinkan AWS AppSync untuk memanggil fungsi Lambda Anda. 

1. Secara opsional, atur respons TTL dan ekspresi reguler validasi token.

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

1. Lampirkan kebijakan berikut ke fungsi Lambda yang digunakan:

   ```
   aws lambda add-permission --function-name "my-function" --statement-id "appsync" --principal appsync.amazonaws.com --action lambda:InvokeFunction --output text 
   ```
**penting**  
Jika Anda ingin kebijakan fungsi dikunci ke satu GraphQL API, Anda dapat menjalankan perintah ini:  

   ```
   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. Perbarui AWS AppSync API Anda untuk menggunakan ARN fungsi Lambda yang diberikan sebagai otorisasi:

   ```
   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"
   ```
**catatan**  
Anda juga dapat menyertakan opsi konfigurasi lain seperti ekspresi reguler token. 

------

Contoh berikut menjelaskan fungsi Lambda yang menunjukkan berbagai otentikasi dan status kegagalan yang dapat dimiliki fungsi Lambda saat digunakan sebagai mekanisme otorisasi: 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 {}
```

### Menghindari batasan otorisasi token SiGv4 dan OIDC
<a name="aws-lambda-authorization-create-new-auth-token"></a>

Metode berikut dapat digunakan untuk menghindari masalah tidak dapat menggunakan tanda tangan SigV4 atau token OIDC Anda sebagai token otorisasi Lambda Anda ketika mode otorisasi tertentu diaktifkan.

Jika Anda ingin menggunakan tanda tangan Sigv4 sebagai token otorisasi Lambda saat mode `AWS_IAM` dan `AWS_LAMBDA` otorisasi diaktifkan untuk API, lakukan AWS AppSync hal berikut:
+ Untuk membuat token otorisasi Lambda baru, tambahkan and/or awalan sufiks acak ke tanda tangan SigV4.
+ Untuk mengambil tanda tangan SiGv4 asli, perbarui fungsi Lambda Anda dengan menghapus and/or sufiks awalan acak dari token otorisasi Lambda. Kemudian, gunakan tanda tangan SiGv4 asli untuk otentikasi.

Jika Anda ingin menggunakan token OIDC sebagai token otorisasi Lambda saat mode otorisasi atau mode `OPENID_CONNECT` otorisasi `AMAZON_COGNITO_USER_POOLS` dan diaktifkan untuk `AWS_LAMBDA` AWS AppSync API, lakukan hal berikut:
+ Untuk membuat token otorisasi Lambda baru, tambahkan and/or awalan sufiks acak ke token OIDC. Token otorisasi Lambda tidak boleh berisi awalan skema Pembawa.
+ Untuk mengambil token OIDC asli, perbarui fungsi Lambda Anda dengan menghapus and/or sufiks awalan acak dari token otorisasi Lambda. Kemudian, gunakan token OIDC asli untuk otentikasi.

## AWS\$1IAM otorisasi
<a name="aws-iam-authorization"></a>

Jenis otorisasi ini memberlakukan [proses penandatanganan versi AWS tanda tangan 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) pada GraphQL API. Anda dapat mengaitkan kebijakan akses Identity and Access Management ([IAM](https://aws.amazon.com/iam/)) dengan jenis otorisasi ini. Aplikasi Anda dapat memanfaatkan asosiasi ini dengan menggunakan kunci akses (yang terdiri dari ID kunci akses dan kunci akses rahasia) atau dengan menggunakan kredensi sementara yang berumur pendek yang disediakan oleh Amazon Cognito Federated Identities.

Jika Anda menginginkan peran yang memiliki akses untuk melakukan semua operasi data:

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

****  

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

------

Anda dapat menemukan `YourGraphQLApiId` dari halaman daftar API utama di AppSync konsol, langsung di bawah nama API Anda. Atau Anda dapat mengambilnya dengan CLI: `aws appsync list-graphql-apis` 

Jika Anda ingin membatasi akses ke operasi GraphQL tertentu saja, Anda dapat melakukan ini untuk `Query` root`Mutation`,, dan bidang. `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>"
         ]
     }
   ]
}
```

------

Misalnya, Anda memiliki skema berikut dan Anda ingin membatasi akses untuk mendapatkan semua posting:

```
schema {
   query: Query
   mutation: Mutation
}

type Query {
   posts:[Post!]!
}

type Mutation {
   addPost(id:ID!, title:String!):Post!
}
```

Kebijakan IAM terkait untuk suatu peran (yang dapat Anda lampirkan ke kumpulan identitas Amazon Cognito, misalnya) akan terlihat seperti berikut:

------
#### [ 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\$1CONNECT otorisasi
<a name="openid-connect-authorization"></a>

Jenis otorisasi ini memberlakukan token [OpenID connect (OIDC](https://openid.net/specs/openid-connect-core-1_0.html)) yang disediakan oleh layanan yang sesuai dengan OIDC. Aplikasi Anda dapat memanfaatkan pengguna dan hak istimewa yang ditentukan oleh penyedia OIDC Anda untuk mengontrol akses.

URL Penerbit adalah satu-satunya nilai konfigurasi wajib yang Anda berikan AWS AppSync (misalnya,`https://auth.example.com`). URL ini harus dapat dialamatkan melalui HTTPS. AWS AppSync [menambahkan `/.well-known/openid-configuration` ke URL penerbit dan menempatkan konfigurasi OpenID sesuai spesifikasi OpenID Connect `https://auth.example.com/.well-known/openid-configuration` Discovery.](https://openid.net/specs/openid-connect-discovery-1_0.html) Ia mengharapkan untuk mengambil dokumen JSON yang [RFC5785](https://tools.ietf.org/html/rfc5785)sesuai di URL ini. Dokumen JSON ini harus berisi `jwks_uri` kunci, yang menunjuk ke dokumen JSON Web Key Set (JWKS) dengan kunci penandatanganan. AWS AppSync mengharuskan JWKS berisi bidang JSON dan. `kty` `kid`

AWS AppSync mendukung berbagai algoritma penandatanganan.


| Algoritme penandatanganan | 
| --- | 
| RS256 | 
| RS384 | 
| RS512 | 
| PS256 | 
| PS384 | 
| PS512 | 
| HS256 | 
| HS384 | 
| HS512 | 
| ES256 | 
| ES384 | 
| ES512 | 

Kami menyarankan Anda menggunakan algoritma RSA. Token yang dikeluarkan oleh penyedia harus mencakup waktu di mana token dikeluarkan (`iat`) dan dapat mencakup waktu di mana token itu diautentikasi (`auth_time`). Anda dapat memberikan nilai TTL untuk waktu yang dikeluarkan (`iatTTL`) dan waktu otentikasi (`authTTL`) dalam konfigurasi OpenID Connect untuk validasi tambahan. Jika penyedia Anda mengotorisasi beberapa aplikasi, Anda juga dapat memberikan ekspresi reguler (`clientId`) yang digunakan untuk mengotorisasi oleh ID klien. Ketika `clientId` ada dalam konfigurasi OpenID Connect Anda, AWS AppSync validasi klaim dengan mewajibkan `clientId` untuk mencocokkan dengan `azp` klaim `aud` atau dalam token.

Untuk memvalidasi beberapa klien, IDs gunakan operator pipeline (“\$1”) yang merupakan “atau” dalam ekspresi reguler. Misalnya, jika aplikasi OIDC Anda memiliki empat klien dengan klien IDs seperti 0A1S2D, 1F4G9H, 1J6L4B, 6 MG, untuk memvalidasi hanya tiga klien pertama, Anda akan menempatkan 1F4G9H \$1 1J6L4B \$1 6 GS5 MG di bidang ID klien. IDs GS5

Jika API dikonfigurasi dengan beberapa jenis otorisasi, AWS AppSync validasi penerbit (klaim iss) yang ada dalam token JWT dari header permintaan dengan membandingkannya dengan URL penerbit yang ditentukan dalam konfigurasi API. Namun, ketika API dikonfigurasi hanya dengan OPENID\$1CONNECT otorisasi, AWS AppSync lewati langkah validasi URL penerbit ini.

## AMAZON\$1COGNITO\$1USER\$1POOLS otorisasi
<a name="amazon-cognito-user-pools-authorization"></a>

Jenis otorisasi ini memberlakukan token OIDC yang disediakan oleh Amazon Cognito User Pools. Aplikasi Anda dapat memanfaatkan pengguna dan grup di pool pengguna dan kumpulan pengguna dari AWS akun lain dan mengaitkannya dengan bidang GraphQL untuk mengontrol akses.

Saat menggunakan Kumpulan Pengguna Amazon Cognito, Anda dapat membuat grup yang menjadi milik pengguna. Informasi ini dikodekan dalam token JWT yang dikirimkan aplikasi Anda AWS AppSync dalam header otorisasi saat mengirim operasi GraphQL. Anda dapat menggunakan arahan GraphQL pada skema untuk mengontrol grup mana yang dapat memanggil resolver mana di lapangan, sehingga memberikan akses yang lebih terkontrol ke pelanggan Anda.

Misalnya, Anda memiliki skema GraphQL berikut:

```
schema {
   query: Query
   mutation: Mutation
}

type Query {
   posts:[Post!]!
}

type Mutation {
   addPost(id:ID!, title:String!):Post!
}
...
```

Jika Anda memiliki dua grup di Amazon Cognito User Pools - blogger dan pembaca - dan Anda ingin membatasi pembaca sehingga mereka tidak dapat menambahkan entri baru, maka skema Anda akan terlihat seperti ini:

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

Perhatikan bahwa Anda dapat menghilangkan `@aws_auth` arahan jika Anda ingin default ke grant-or-deny strategi akses tertentu. Anda dapat menentukan grant-or-deny strategi dalam konfigurasi kumpulan pengguna saat membuat GraphQL API melalui konsol atau melalui perintah CLI berikut:

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

## Menggunakan mode otorisasi tambahan
<a name="using-additional-authorization-modes"></a>

Saat Anda menambahkan mode otorisasi tambahan, Anda dapat langsung mengonfigurasi pengaturan otorisasi di level API AWS AppSync GraphQL (yaitu, `authenticationType` bidang yang dapat Anda konfigurasikan langsung pada `GraphqlApi` objek) dan bertindak sebagai default pada skema. Ini berarti bahwa jenis apa pun yang tidak memiliki arahan khusus harus melewati pengaturan otorisasi tingkat API.

Pada tingkat skema, Anda dapat menentukan mode otorisasi tambahan menggunakan arahan pada skema. Anda dapat menentukan mode otorisasi pada bidang individual dalam skema. Misalnya, untuk `API_KEY` otorisasi yang akan Anda gunakan `@aws_api_key` pada definisi/bidang tipe objek skema. Arahan berikut didukung pada bidang skema dan definisi tipe objek:
+  `@aws_api_key`- Untuk menentukan bidang `API_KEY` diotorisasi.
+  `@aws_iam`- Untuk menentukan bahwa bidang tersebut `AWS_IAM` diotorisasi.
+  `@aws_oidc`- Untuk menentukan bahwa bidang tersebut `OPENID_CONNECT` diotorisasi.
+  `@aws_cognito_user_pools`- Untuk menentukan bahwa bidang tersebut `AMAZON_COGNITO_USER_POOLS` diotorisasi.
+  `@aws_lambda`- Untuk menentukan bahwa bidang tersebut `AWS_LAMBDA` diotorisasi.

Anda tidak dapat menggunakan `@aws_auth` arahan bersama dengan mode otorisasi tambahan. `@aws_auth`hanya berfungsi dalam konteks `AMAZON_COGNITO_USER_POOLS` otorisasi tanpa mode otorisasi tambahan. Namun, Anda dapat menggunakan `@aws_cognito_user_pools` direktif sebagai pengganti `@aws_auth` direktif, menggunakan argumen yang sama. Perbedaan utama antara keduanya adalah bahwa Anda dapat menentukan `@aws_cognito_user_pools` pada setiap bidang dan definisi jenis objek.

Untuk memahami bagaimana mode otorisasi tambahan bekerja dan bagaimana mereka dapat ditentukan pada skema, mari kita lihat skema berikut:

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

Untuk skema ini, asumsikan bahwa itu `AWS_IAM` adalah jenis otorisasi default pada AWS AppSync GraphQL API. Ini berarti bahwa bidang yang tidak memiliki arahan dilindungi menggunakan`AWS_IAM`. Misalnya, itulah kasus untuk `getPost` bidang pada `Query` tipe. Arahan skema memungkinkan Anda untuk menggunakan lebih dari satu mode otorisasi. Misalnya, Anda dapat `API_KEY` mengonfigurasi sebagai mode otorisasi tambahan pada AWS AppSync GraphQL API, dan Anda dapat menandai bidang menggunakan arahan (misalnya, `@aws_api_key` dalam contoh `getAllPosts` ini). Arahan bekerja di tingkat lapangan sehingga Anda perlu memberikan `API_KEY` akses ke `Post` jenis juga. Anda dapat melakukan ini dengan menandai setiap bidang dalam `Post` tipe dengan direktif, atau dengan menandai `Post` tipe dengan `@aws_api_key` direktif.

Untuk lebih membatasi akses ke bidang dalam `Post` jenis, Anda dapat menggunakan arahan terhadap bidang individual dalam `Post` jenis seperti yang ditunjukkan berikut.

Misalnya, Anda dapat menambahkan `restrictedContent` bidang ke `Post` jenis dan membatasi akses ke sana dengan menggunakan `@aws_iam` direktif. `AWS_IAM`Permintaan yang diautentikasi dapat mengakses`restrictedContent`, namun `API_KEY` permintaan tidak akan dapat mengaksesnya.

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

## Kontrol akses detail
<a name="fine-grained-access-control"></a>

Informasi sebelumnya menunjukkan cara membatasi atau memberikan akses ke bidang GraphQL tertentu. Jika Anda ingin mengatur kontrol akses pada data berdasarkan kondisi tertentu (misalnya, berdasarkan pengguna yang melakukan panggilan dan apakah pengguna memiliki data), Anda dapat menggunakan templat pemetaan di resolver Anda. Anda juga dapat melakukan logika bisnis yang lebih kompleks, yang kami jelaskan dalam [Memfilter Informasi](#aws-appsync-filtering-information).

Bagian ini menunjukkan cara mengatur kontrol akses pada data Anda menggunakan template pemetaan DynamoDB resolver.

[Sebelum melanjutkan lebih jauh, jika Anda tidak terbiasa dengan template pemetaan di AWS AppSync, Anda mungkin ingin meninjau referensi template pemetaan [Resolver dan referensi template pemetaan Resolver](resolver-mapping-template-reference.md#aws-appsync-resolver-mapping-template-reference) untuk DynamoDB.](resolver-mapping-template-reference-dynamodb.md#aws-appsync-resolver-mapping-template-reference-dynamodb)

Dalam contoh berikut menggunakan DynamoDB, misalkan Anda menggunakan skema posting blog sebelumnya, dan hanya pengguna yang membuat posting yang diizinkan untuk mengeditnya. Proses evaluasi akan bagi pengguna untuk mendapatkan kredensil dalam aplikasi mereka, menggunakan Amazon Cognito User Pools misalnya, dan kemudian meneruskan kredensil ini sebagai bagian dari operasi GraphQL. Template pemetaan kemudian akan menggantikan nilai dari kredensional (seperti nama pengguna) dalam pernyataan bersyarat yang kemudian akan dibandingkan dengan nilai dalam database Anda.

![\[Diagram showing authentication flow from user login to database operation using Layanan AWS.\]](http://docs.aws.amazon.com/id_id/appsync/latest/devguide/images/FGAC.png)


Untuk menambahkan fungsi ini, tambahkan bidang `editPost` GraphQL sebagai berikut:

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

Template pemetaan resolver untuk `editPost` (ditampilkan dalam contoh di akhir bagian ini) perlu melakukan pemeriksaan logis terhadap penyimpanan data Anda untuk mengizinkan hanya pengguna yang membuat posting untuk mengeditnya. Karena ini adalah operasi edit, ini sesuai dengan DynamoDB `UpdateItem` di. Anda dapat melakukan pemeriksaan bersyarat sebelum melakukan tindakan ini, menggunakan konteks yang diteruskan untuk validasi identitas pengguna. Ini disimpan dalam `Identity` objek yang memiliki nilai-nilai berikut:

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

Untuk menggunakan objek ini dalam panggilan `UpdateItem` DynamoDB, Anda perlu menyimpan informasi identitas pengguna dalam tabel untuk perbandingan. Pertama, `addPost` mutasi Anda perlu menyimpan pencipta. Kedua, `editPost` mutasi Anda perlu melakukan pemeriksaan bersyarat sebelum memperbarui.

Berikut adalah contoh kode resolver `addPost` yang menyimpan identitas pengguna sebagai `Author` kolom:

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

Perhatikan bahwa `Author` atribut diisi dari `Identity` objek, yang berasal dari aplikasi.

Terakhir, berikut adalah contoh kode resolver untuk`editPost`, yang hanya memperbarui konten posting blog jika permintaan berasal dari pengguna yang membuat posting:

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

Contoh ini menggunakan a `PutItem` yang menimpa semua nilai daripada`UpdateItem`, tetapi konsep yang sama berlaku pada blok `condition` pernyataan.

## Informasi penyaringan
<a name="aws-appsync-filtering-information"></a>

Mungkin ada kasus di mana Anda tidak dapat mengontrol respons dari sumber data Anda, tetapi Anda tidak ingin mengirim informasi yang tidak perlu kepada klien saat berhasil menulis atau membaca ke sumber data. Dalam kasus ini, Anda dapat memfilter informasi dengan menggunakan template pemetaan respons.

Misalnya, Anda tidak memiliki indeks yang sesuai pada tabel DynamoDB posting blog Anda (seperti indeks pada). `Author` Anda dapat menggunakan resolver berikut:

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

Handler permintaan mengambil item bahkan jika pemanggil bukan penulis yang membuat posting. Untuk mencegah hal ini mengembalikan semua data, penangan respons memeriksa untuk memastikan pemanggil cocok dengan penulis item. Jika pemanggil tidak cocok dengan pemeriksaan ini, hanya respons nol yang dikembalikan.

## Akses sumber data
<a name="data-source-access"></a>

AWS AppSync berkomunikasi dengan sumber data menggunakan peran Identity and Access Management ([IAM](https://aws.amazon.com/iam/)) dan kebijakan akses. Jika Anda menggunakan peran yang ada, Kebijakan Kepercayaan perlu ditambahkan AWS AppSync agar dapat mengambil peran tersebut. Hubungan kepercayaan akan terlihat seperti di bawah ini:

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

****  

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

------

Penting untuk mengurangi kebijakan akses pada peran agar hanya memiliki izin untuk bertindak berdasarkan kumpulan sumber daya minimal yang diperlukan. Saat menggunakan AppSync konsol untuk membuat sumber data dan membuat peran, ini dilakukan secara otomatis untuk Anda. Namun saat menggunakan templat sampel bawaan dari konsol IAM untuk membuat peran di luar AWS AppSync konsol, izin tidak akan dicakup secara otomatis pada sumber daya dan Anda harus melakukan tindakan ini sebelum memindahkan aplikasi ke produksi.

# Kasus penggunaan kontrol akses untuk mengamankan permintaan dan tanggapan
<a name="security-authorization-use-cases"></a>

Di bagian [Keamanan](security-authz.md#aws-appsync-security), Anda mempelajari tentang berbagai mode Otorisasi untuk melindungi API Anda dan pengenalan diberikan pada mekanisme Otorisasi Berbutir Halus untuk memahami konsep dan alur. Karena AWS AppSync memungkinkan Anda untuk melakukan operasi penuh logika pada data melalui penggunaan template [Pemetaan GraphQL Resolver](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview), Anda dapat melindungi data saat membaca atau menulis dengan cara yang sangat fleksibel menggunakan kombinasi identitas pengguna, persyaratan, dan injeksi data.

Jika Anda tidak terbiasa dengan mengedit AWS AppSync Resolvers, tinjau panduan [pemrograman](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide).

## Ikhtisar
<a name="overview"></a>

Pemberian akses ke data dalam sistem secara tradisional dilakukan melalui [matriks kontrol Akses](https://en.wikipedia.org/wiki/Access_Control_Matrix) di mana persimpangan baris (sumber daya) dan kolom (pengguna/peran) adalah izin yang diberikan.

AWS AppSync menggunakan sumber daya di akun Anda sendiri dan memasukkan informasi identitas (pengguna/peran) ke dalam permintaan dan respons GraphQL sebagai [objek konteks](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference), yang dapat Anda gunakan dalam resolver. Ini berarti bahwa izin dapat diberikan dengan tepat baik pada operasi tulis atau baca berdasarkan logika resolver. Jika logika ini berada pada tingkat sumber daya, misalnya hanya pengguna atau grup bernama tertentu yang dapat read/write ke baris database tertentu, maka “metadata otorisasi” itu harus disimpan. AWS AppSync tidak menyimpan data apa pun sehingga Anda harus menyimpan metadata otorisasi ini dengan sumber daya sehingga izin dapat dihitung. **Metadata otorisasi biasanya merupakan atribut (kolom) dalam tabel DynamoDB, seperti pemilik atau daftar pengguna/grup.** Misalnya mungkin ada atribut **Pembaca** dan **Penulis**.

Dari tingkat tinggi, artinya ini adalah jika Anda membaca item individual dari sumber data, Anda melakukan `#if () ... #end` pernyataan bersyarat di templat respons setelah resolver membaca dari sumber data. Pemeriksaan biasanya akan menggunakan nilai pengguna atau grup `$context.identity` untuk pemeriksaan keanggotaan terhadap metadata otorisasi yang dikembalikan dari operasi baca. Untuk beberapa catatan, seperti daftar yang dikembalikan dari tabel `Scan` atau`Query`, Anda akan mengirim pemeriksaan kondisi sebagai bagian dari operasi ke sumber data menggunakan nilai pengguna atau grup yang serupa.

Demikian pula saat menulis data, Anda akan menerapkan pernyataan bersyarat ke tindakan (seperti `PutItem` atau `UpdateItem` untuk melihat apakah pengguna atau grup yang membuat mutasi memiliki izin. Kondisional lagi akan berkali-kali menggunakan nilai `$context.identity` untuk membandingkan dengan metadata otorisasi pada sumber daya itu. Untuk templat permintaan dan respons, Anda juga dapat menggunakan header khusus dari klien untuk melakukan pemeriksaan validasi.

## Membaca data
<a name="reading-data"></a>

Seperti diuraikan di atas, metadata otorisasi untuk melakukan pemeriksaan harus disimpan dengan sumber daya atau diteruskan ke permintaan GraphQL (identitas, header, dll.). Untuk menunjukkan ini misalkan Anda memiliki tabel DynamoDB di bawah ini:

![\[DynamoDB table with ID, Data, PeopleCanAccess, GroupsCanAccess, and Owner columns.\]](http://docs.aws.amazon.com/id_id/appsync/latest/devguide/images/auth.png)


Kunci utama adalah `id` dan data yang akan diakses adalah`Data`. Kolom lainnya adalah contoh pemeriksaan yang dapat Anda lakukan untuk otorisasi. `Owner`akan memakan `String` waktu lama `PeopleCanAccess` dan `GroupsCanAccess` akan `String Sets` seperti yang diuraikan dalam [referensi template pemetaan Resolver](resolver-mapping-template-reference-dynamodb.md#aws-appsync-resolver-mapping-template-reference-dynamodb) untuk DynamoDB.

Dalam [ikhtisar template pemetaan resolver](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview) diagram menunjukkan bagaimana template respons tidak hanya berisi objek konteks tetapi juga hasil dari sumber data. Untuk kueri GraphQL dari masing-masing item, Anda dapat menggunakan template respons untuk memeriksa apakah pengguna diizinkan untuk melihat hasil ini atau mengembalikan pesan kesalahan otorisasi. Ini kadang-kadang disebut sebagai “Filter otorisasi”. Untuk query GraphQL mengembalikan daftar, menggunakan Scan atau Query, akan lebih baik untuk melakukan pemeriksaan pada template permintaan dan mengembalikan data hanya jika kondisi otorisasi terpenuhi. Implementasinya kemudian:

1. GetItem - pemeriksaan otorisasi untuk catatan individu. Selesai menggunakan `#if() ... #end` pernyataan.

1. Operasi Scan/Query - pemeriksaan otorisasi adalah pernyataan. `"filter":{"expression":...}` Pemeriksaan umum adalah kesetaraan (`attribute = :input`) atau memeriksa apakah nilai ada dalam daftar (`contains(attribute, :input)`).

Dalam \$12 `attribute` dalam kedua pernyataan mewakili nama kolom catatan dalam tabel, seperti `Owner` dalam contoh di atas. Anda dapat alias ini dengan `#` tanda dan penggunaan `"expressionNames":{...}` tetapi itu tidak wajib. `:input`Ini adalah referensi ke nilai yang Anda bandingkan dengan atribut database, yang akan Anda definisikan`"expressionValues":{...}`. Anda akan melihat contoh-contoh di bawah ini.

### Kasus penggunaan: pemilik dapat membaca
<a name="use-case-owner-can-read"></a>

Menggunakan tabel di atas, jika Anda hanya ingin mengembalikan data jika `Owner == Nadia` untuk operasi baca individu (`GetItem`) template Anda akan terlihat seperti:

```
#if($context.result["Owner"] == $context.identity.username)
    $utils.toJson($context.result)
#else
    $utils.unauthorized()
#end
```

Beberapa hal yang perlu disebutkan di sini yang akan digunakan kembali di bagian yang tersisa. Pertama, cek menggunakan `$context.identity.username` yang akan menjadi nama pendaftaran pengguna yang ramah jika kumpulan pengguna Amazon Cognito digunakan dan akan menjadi identitas pengguna jika IAM digunakan (termasuk Identitas Federasi Amazon Cognito). Ada nilai lain yang harus disimpan bagi pemilik seperti nilai unik “identitas Amazon Cognito”, yang berguna saat menggabungkan login dari beberapa lokasi, dan Anda harus meninjau opsi yang tersedia di Referensi Konteks Template [Pemetaan Resolver](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference).

Kedua, pemeriksaan kondisional else yang merespons sepenuhnya opsional tetapi direkomendasikan sebagai praktik terbaik saat mendesain GraphQL API Anda. `$util.unauthorized()`

### Kasus penggunaan: akses khusus hardcode
<a name="use-case-hardcode-specific-access"></a>

```
// This checks if the user is part of the Admin group and makes the call
#foreach($group in $context.identity.claims.get("cognito:groups"))
    #if($group == "Admin")
        #set($inCognitoGroup = true)
    #end
#end
#if($inCognitoGroup)
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "attributeValues" : {
        "owner" : $util.dynamodb.toDynamoDBJson($context.identity.username)
        #foreach( $entry in $context.arguments.entrySet() )
            ,"${entry.key}" : $util.dynamodb.toDynamoDBJson($entry.value)
        #end
    }
}
#else
    $utils.unauthorized()
#end
```

### Kasus penggunaan: memfilter daftar hasil
<a name="use-case-filtering-a-list-of-results"></a>

Dalam contoh sebelumnya Anda dapat melakukan pemeriksaan terhadap `$context.result` secara langsung karena mengembalikan satu item, namun beberapa operasi seperti pemindaian akan mengembalikan beberapa item di `$context.result.items` mana Anda perlu melakukan filter otorisasi dan hanya mengembalikan hasil yang diizinkan pengguna untuk melihat. Misalkan `Owner` bidang memiliki IdentityId Amazon Cognito kali ini ditetapkan pada catatan, Anda kemudian dapat menggunakan template pemetaan respons berikut untuk memfilter agar hanya menampilkan catatan yang dimiliki pengguna:

```
#set($myResults = [])
#foreach($item in $context.result.items)
    ##For userpools use $context.identity.username instead
    #if($item.Owner == $context.identity.cognitoIdentityId)
        #set($added = $myResults.add($item))
    #end
#end
$utils.toJson($myResults)
```

### Kasus penggunaan: banyak orang dapat membaca
<a name="use-case-multiple-people-can-read"></a>

Opsi otorisasi populer lainnya adalah mengizinkan sekelompok orang untuk dapat membaca data. Dalam contoh di bawah ini `"filter":{"expression":...}` hanya mengembalikan nilai dari pemindaian tabel jika pengguna yang menjalankan kueri GraphQL tercantum dalam set untuk. `PeopleCanAccess`

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": #if(${context.arguments.count}) $util.toJson($context.arguments.count) #else 20 #end,
    "nextToken": #if(${context.arguments.nextToken})  $util.toJson($context.arguments.nextToken) #else null #end,
    "filter":{
        "expression": "contains(#peopleCanAccess, :value)",
        "expressionNames": {
                "#peopleCanAccess": "peopleCanAccess"
        },
        "expressionValues": {
                ":value": $util.dynamodb.toDynamoDBJson($context.identity.username)
        }
    }
}
```

### Kasus penggunaan: grup dapat membaca
<a name="use-case-group-can-read"></a>

Mirip dengan kasus penggunaan terakhir, mungkin hanya orang dalam satu atau lebih grup yang memiliki hak untuk membaca item tertentu dalam database. Penggunaan `"expression": "contains()"` operasi serupa namun ini adalah logis-atau dari semua grup yang mungkin menjadi bagian dari pengguna yang perlu diperhitungkan dalam keanggotaan yang ditetapkan. Dalam hal ini kami membuat `$expression` pernyataan di bawah ini untuk setiap grup tempat pengguna berada dan kemudian meneruskannya ke filter:

```
#set($expression = "")
#set($expressionValues = {})
#foreach($group in $context.identity.claims.get("cognito:groups"))
    #set( $expression = "${expression} contains(groupsCanAccess, :var$foreach.count )" )
    #set( $val = {})
    #set( $test = $val.put("S", $group))
    #set( $values = $expressionValues.put(":var$foreach.count", $val))
    #if ( $foreach.hasNext )
    #set( $expression = "${expression} OR" )
    #end
#end
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": #if(${context.arguments.count}) $util.toJson($context.arguments.count) #else 20 #end,
    "nextToken": #if(${context.arguments.nextToken})  $util.toJson($context.arguments.nextToken) #else null #end,
    "filter":{
        "expression": "$expression",
        "expressionValues": $utils.toJson($expressionValues)
    }
}
```

## Menulis data
<a name="writing-data"></a>

Menulis data tentang mutasi selalu dikontrol pada template pemetaan permintaan. Dalam kasus sumber data DynamoDB, kuncinya adalah menggunakan yang `"condition":{"expression"...}"` sesuai yang melakukan validasi terhadap metadata otorisasi dalam tabel tersebut. Di [Keamanan](security-authz.md#aws-appsync-security), kami memberikan contoh yang dapat Anda gunakan untuk memeriksa `Author` bidang dalam tabel. Kasus penggunaan di bagian ini mengeksplorasi lebih banyak kasus penggunaan.

### Kasus penggunaan: banyak pemilik
<a name="use-case-multiple-owners"></a>

Menggunakan diagram tabel contoh dari sebelumnya, misalkan `PeopleCanAccess` daftarnya

```
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "update" : {
        "expression" : "SET meta = :meta",
        "expressionValues": {
            ":meta" : $util.dynamodb.toDynamoDBJson($ctx.args.meta)
        }
    },
    "condition" : {
        "expression"       : "contains(Owner,:expectedOwner)",
        "expressionValues" : {
            ":expectedOwner" : $util.dynamodb.toDynamoDBJson($context.identity.username)
        }
    }
}
```

### Kasus penggunaan: grup dapat membuat catatan baru
<a name="use-case-group-can-create-new-record"></a>

```
#set($expression = "")
#set($expressionValues = {})
#foreach($group in $context.identity.claims.get("cognito:groups"))
    #set( $expression = "${expression} contains(groupsCanAccess, :var$foreach.count )" )
    #set( $val = {})
    #set( $test = $val.put("S", $group))
    #set( $values = $expressionValues.put(":var$foreach.count", $val))
    #if ( $foreach.hasNext )
    #set( $expression = "${expression} OR" )
    #end
#end
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        ## If your table's hash key is not named 'id', update it here. **
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
        ## If your table has a sort key, add it as an item here. **
    },
    "attributeValues" : {
        ## Add an item for each field you would like to store to Amazon DynamoDB. **
        "title" : $util.dynamodb.toDynamoDBJson($ctx.args.title),
        "content": $util.dynamodb.toDynamoDBJson($ctx.args.content),
        "owner": $util.dynamodb.toDynamoDBJson($context.identity.username)
    },
    "condition" : {
        "expression": $util.toJson("attribute_not_exists(id) AND $expression"),
        "expressionValues": $utils.toJson($expressionValues)
    }
}
```

### Kasus penggunaan: grup dapat memperbarui catatan yang ada
<a name="use-case-group-can-update-existing-record"></a>

```
#set($expression = "")
#set($expressionValues = {})
#foreach($group in $context.identity.claims.get("cognito:groups"))
    #set( $expression = "${expression} contains(groupsCanAccess, :var$foreach.count )" )
    #set( $val = {})
    #set( $test = $val.put("S", $group))
    #set( $values = $expressionValues.put(":var$foreach.count", $val))
    #if ( $foreach.hasNext )
    #set( $expression = "${expression} OR" )
    #end
#end
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "update":{
                "expression" : "SET title = :title, content = :content",
        "expressionValues": {
            ":title" : $util.dynamodb.toDynamoDBJson($ctx.args.title),
            ":content" : $util.dynamodb.toDynamoDBJson($ctx.args.content)
        }
    },
    "condition" : {
        "expression": $util.toJson($expression),
        "expressionValues": $utils.toJson($expressionValues)
    }
}
```

## Catatan publik dan pribadi
<a name="public-and-private-records"></a>

Dengan filter bersyarat Anda juga dapat memilih untuk menandai data sebagai pribadi, publik atau pemeriksaan Boolean lainnya. Ini kemudian dapat digabungkan sebagai bagian dari filter otorisasi di dalam template respons. Menggunakan pemeriksaan ini adalah cara yang bagus untuk menyembunyikan data sementara atau menghapusnya dari tampilan tanpa mencoba mengontrol keanggotaan grup.

Misalnya Anda menambahkan atribut pada setiap item dalam tabel DynamoDB Anda `public` dipanggil dengan nilai atau. `yes` `no` Template respons berikut dapat digunakan pada `GetItem` panggilan untuk hanya menampilkan data jika pengguna berada dalam grup yang memiliki akses DAN jika data tersebut ditandai sebagai publik:

```
#set($permissions = $context.result.GroupsCanAccess)
#set($claimPermissions = $context.identity.claims.get("cognito:groups"))

#foreach($per in $permissions)
    #foreach($cgroups in $claimPermissions)
        #if($cgroups == $per)
            #set($hasPermission = true)
        #end
    #end
#end

#if($hasPermission && $context.result.public == 'yes')
    $utils.toJson($context.result)
#else
    $utils.unauthorized()
#end
```

Kode di atas juga dapat menggunakan OR logis (`||`) untuk memungkinkan orang membaca jika mereka memiliki izin untuk merekam atau jika itu publik:

```
#if($hasPermission || $context.result.public == 'yes')
    $utils.toJson($context.result)
#else
    $utils.unauthorized()
#end
```

Secara umum, Anda akan menemukan operator standar`==`,, `!=``&&`, dan `||` membantu saat melakukan pemeriksaan otorisasi.

## Data waktu nyata
<a name="security-real-time-data"></a>

Anda dapat menerapkan Kontrol Akses Berbutir Halus ke langganan GraphQL pada saat klien membuat langganan, menggunakan teknik yang sama yang dijelaskan sebelumnya dalam dokumentasi ini. Anda melampirkan resolver ke bidang langganan, di mana Anda dapat melakukan kueri data dari sumber data dan melakukan logika bersyarat baik dalam templat pemetaan permintaan atau respons. Anda juga dapat mengembalikan data tambahan ke klien, seperti hasil awal dari langganan, selama struktur data cocok dengan jenis yang dikembalikan dalam langganan GraphQL Anda.

### Kasus penggunaan: pengguna hanya dapat berlangganan percakapan tertentu
<a name="use-case-user-can-subscribe-to-specific-conversations-only"></a>

Kasus penggunaan umum untuk data real-time dengan langganan GraphQL adalah membangun aplikasi perpesanan atau obrolan pribadi. Saat membuat aplikasi obrolan yang memiliki banyak pengguna, percakapan dapat terjadi antara dua orang atau di antara banyak orang. Ini dapat dikelompokkan ke dalam “kamar”, yang bersifat pribadi atau publik. Dengan demikian, Anda hanya ingin memberi wewenang kepada pengguna untuk berlangganan percakapan (yang bisa berupa satu lawan satu atau di antara grup) yang telah diberikan aksesnya. Untuk tujuan demonstrasi, contoh di bawah ini menunjukkan kasus penggunaan sederhana dari satu pengguna mengirim pesan pribadi ke yang lain. Pengaturan memiliki dua tabel Amazon DynamoDB:
+ Tabel pesan: (kunci utama)`toUser`, (kunci sortir) `id` 
+ Tabel izin: (kunci utama) `username` 

Tabel Pesan menyimpan pesan aktual yang dikirim melalui mutasi GraphQL. Tabel Izin diperiksa oleh langganan GraphQL untuk otorisasi pada waktu koneksi klien. Contoh di bawah ini mengasumsikan Anda menggunakan skema GraphQL berikut:

```
input CreateUserPermissionsInput {
    user: String!
    isAuthorizedForSubscriptions: Boolean
}

type Message {
    id: ID
    toUser: String
    fromUser: String
    content: String
}

type MessageConnection {
    items: [Message]
    nextToken: String
}

type Mutation {
    sendMessage(toUser: String!, content: String!): Message
    createUserPermissions(input: CreateUserPermissionsInput!): UserPermissions
    updateUserPermissions(input: UpdateUserPermissionInput!): UserPermissions
}

type Query {
    getMyMessages(first: Int, after: String): MessageConnection
    getUserPermissions(user: String!): UserPermissions
}

type Subscription {
    newMessage(toUser: String!): Message
        @aws_subscribe(mutations: ["sendMessage"])
}

input UpdateUserPermissionInput {
    user: String!
    isAuthorizedForSubscriptions: Boolean
}

type UserPermissions {
    user: String
    isAuthorizedForSubscriptions: Boolean
}

schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}
```

Beberapa operasi standar, seperti`createUserPermissions()`, tidak tercakup di bawah ini untuk menggambarkan resolver langganan, tetapi merupakan implementasi standar dari DynamoDB resolver. Sebagai gantinya, kami akan fokus pada alur otorisasi berlangganan dengan resolver. Untuk mengirim pesan dari satu pengguna ke pengguna lain, lampirkan resolver ke `sendMessage()` bidang dan pilih sumber data tabel **Pesan** dengan templat permintaan berikut:

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "toUser" : $util.dynamodb.toDynamoDBJson($ctx.args.toUser),
        "id" : $util.dynamodb.toDynamoDBJson($util.autoId())
    },
    "attributeValues" : {
        "fromUser" : $util.dynamodb.toDynamoDBJson($context.identity.username),
        "content" : $util.dynamodb.toDynamoDBJson($ctx.args.content),
    }
}
```

Dalam contoh ini, kami menggunakan `$context.identity.username`. Ini mengembalikan informasi pengguna untuk AWS Identity and Access Management atau pengguna Amazon Cognito. Template respons adalah passthrough sederhana dari. `$util.toJson($ctx.result)` Simpan dan kembali ke halaman skema. Kemudian lampirkan resolver untuk `newMessage()` langganan, menggunakan tabel **Izin** sebagai sumber data dan template pemetaan permintaan berikut:

```
{
    "version": "2018-05-29",
    "operation": "GetItem",
    "key": {
        "username": $util.dynamodb.toDynamoDBJson($ctx.identity.username),
    },
}
```

Kemudian gunakan template pemetaan respons berikut untuk melakukan pemeriksaan otorisasi menggunakan data dari tabel **Izin**:

```
#if(! ${context.result})
    $utils.unauthorized()
#elseif(${context.identity.username} != ${context.arguments.toUser})
    $utils.unauthorized()
#elseif(! ${context.result.isAuthorizedForSubscriptions})
    $utils.unauthorized()
#else
##User is authorized, but we return null to continue
    null
#end
```

Dalam hal ini, Anda melakukan tiga pemeriksaan otorisasi. Yang pertama memastikan bahwa hasilnya dikembalikan. Yang kedua memastikan bahwa pengguna tidak berlangganan pesan yang dimaksudkan untuk orang lain. Yang ketiga memastikan bahwa pengguna diizinkan untuk berlangganan ke bidang apa pun, dengan memeriksa atribut DynamoDB disimpan sebagai file`isAuthorizedForSubscriptions`. `BOOL`

Untuk menguji semuanya, Anda dapat masuk ke AWS AppSync konsol menggunakan kumpulan pengguna Amazon Cognito dan pengguna bernama “Nadia”, lalu menjalankan langganan GraphQL berikut:

```
subscription AuthorizedSubscription {
    newMessage(toUser: "Nadia") {
        id
        toUser
        fromUser
        content
    }
}
```

Jika dalam tabel **Izin** ada catatan untuk atribut `username` kunci `Nadia` dengan `isAuthorizedForSubscriptions` set to`true`, Anda akan melihat respons yang berhasil. Jika Anda mencoba yang berbeda `username` dalam `newMessage()` kueri di atas, kesalahan akan dikembalikan.

# Gunakan AWS WAF untuk melindungi Anda AWS AppSync APIs
<a name="WAF-Integration"></a>

AWS WAF adalah firewall aplikasi web yang membantu melindungi aplikasi web dan APIs dari serangan. Ini memungkinkan Anda untuk mengonfigurasi seperangkat aturan, yang disebut daftar kontrol akses web (web ACL), yang memungkinkan, memblokir, atau memantau (menghitung) permintaan web berdasarkan aturan dan kondisi keamanan web yang dapat disesuaikan yang Anda tentukan. Saat mengintegrasikan AWS AppSync API AWS WAF, Anda mendapatkan lebih banyak kontrol dan visibilitas ke lalu lintas HTTP yang diterima oleh API Anda. Untuk mempelajari selengkapnya AWS WAF, lihat [Cara AWS WAF Kerja](https://docs.aws.amazon.com/waf/latest/developerguide/how-aws-waf-works.html) di Panduan AWS WAF Pengembang. 

Anda dapat menggunakan AWS WAF untuk melindungi AppSync API Anda dari eksploitasi web umum, seperti injeksi SQL dan serangan cross-site scripting (XSS). Ini dapat memengaruhi ketersediaan dan kinerja API, membahayakan keamanan, atau mengkonsumsi sumber daya yang berlebihan. Misalnya, Anda dapat membuat aturan untuk mengizinkan atau memblokir permintaan dari rentang alamat IP tertentu, permintaan dari blok CIDR, permintaan yang berasal dari negara atau wilayah tertentu, permintaan yang berisi kode SQL berbahaya, atau permintaan yang berisi skrip berbahaya.

Anda juga dapat membuat aturan yang cocok dengan string tertentu atau pola ekspresi reguler di header HTTP, metode, string kueri, URI, dan badan permintaan (terbatas pada 8 KB pertama). Selain itu, Anda dapat membuat aturan untuk memblokir serangan dari agen pengguna tertentu, bot buruk, dan pencakar konten. Misalnya, Anda dapat menggunakan aturan berbasis tarif untuk menentukan jumlah permintaan web yang diizinkan oleh setiap IP klien dalam periode 5 menit yang terus diperbarui.

Untuk mempelajari lebih lanjut tentang jenis aturan yang didukung dan AWS WAF fitur tambahan, lihat [Panduan AWS WAF Pengembang](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) dan [Referensi AWS WAF API](https://docs.aws.amazon.com/waf/latest/APIReference/API_Types_AWS_WAFV2.html).

**penting**  
AWS WAF adalah garis pertahanan pertama Anda terhadap eksploitasi web. Bila AWS WAF diaktifkan pada API, AWS WAF aturan dievaluasi sebelum fitur kontrol akses lainnya, seperti otorisasi kunci API, kebijakan IAM, token OIDC, dan kumpulan pengguna Amazon Cognito. 

## Integrasikan AppSync API dengan AWS WAF
<a name="integrate-API-with-WAF"></a>

Anda dapat mengintegrasikan API Appsync dengan AWS WAF menggunakan Konsol Manajemen AWS,, AWS CLI AWS CloudFormation, atau klien lain yang kompatibel.

**Untuk mengintegrasikan AWS AppSync API dengan AWS WAF**

1. Buat ACL AWS WAF web. Untuk langkah-langkah mendetail menggunakan [AWS WAF Konsol](https://console.aws.amazon.com/waf/), lihat [Membuat ACL web](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-creating.html).

1. Tentukan aturan untuk ACL web. Aturan atau aturan didefinisikan dalam proses pembuatan ACL web. Untuk informasi tentang cara menyusun aturan, lihat [AWS WAF aturan](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rules.html). Untuk contoh aturan berguna yang dapat Anda tentukan untuk AWS AppSync API, lihat[Membuat aturan untuk ACL web](#Creating-web-acl-rules).

1. Kaitkan ACL web dengan AWS AppSync API. Anda dapat melakukan langkah ini di [AWS WAF Konsol](https://console.aws.amazon.com/wafv2/) atau di [AppSync Konsol](https://console.aws.amazon.com/appsync/). 
   + Untuk mengaitkan ACL web dengan AWS AppSync API di AWS WAF Konsol, ikuti petunjuk untuk [Mengaitkan atau memisahkan ACL Web dengan AWS sumber daya](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-associating-aws-resource.html) di Panduan Pengembang. AWS WAF 
   + Untuk mengaitkan ACL web dengan AWS AppSync API di Konsol AWS AppSync 

     1. Masuk ke Konsol Manajemen AWS dan buka [AppSync Konsol](https://console.aws.amazon.com/appsync/).

     1. Pilih API yang ingin Anda kaitkan dengan ACL web.

     1. Pada panel navigasi, silakan pilih **Pengaturan**.

     1. Di bagian **firewall aplikasi Web**, nyalakan **Aktifkan AWS WAF**.

     1. Dalam daftar dropdown **Web ACL**, pilih nama ACL web untuk dikaitkan dengan API Anda.

     1. Pilih **Simpan** untuk mengaitkan ACL web dengan API Anda.

   

**catatan**  
Setelah Anda membuat ACL web di AWS WAF Konsol, diperlukan beberapa menit agar ACL web baru tersedia. Jika Anda tidak melihat ACL web yang baru dibuat di menu **firewall aplikasi Web**, tunggu beberapa menit dan coba lagi langkah-langkah untuk mengaitkan ACL web dengan API Anda.

**catatan**  
AWS WAF integrasi hanya mendukung `Subscription registration message` acara untuk titik akhir waktu nyata. AWS AppSync akan merespons dengan pesan kesalahan alih-alih `start_ack` pesan untuk apa pun yang `Subscription registration message` diblokir oleh AWS WAF. 

Setelah Anda mengaitkan ACL web dengan AWS AppSync API, Anda akan mengelola ACL web menggunakan. AWS WAF APIs Anda tidak perlu mengaitkan kembali ACL web dengan AWS AppSync API Anda kecuali Anda ingin mengaitkan AWS AppSync API dengan ACL web yang berbeda.

## Membuat aturan untuk ACL web
<a name="Creating-web-acl-rules"></a>

Aturan menentukan cara memeriksa permintaan web dan apa yang harus dilakukan ketika permintaan web cocok dengan kriteria inspeksi. Aturan tidak ada dengan AWS WAF sendirinya. Anda dapat mengakses aturan berdasarkan nama di grup aturan atau di ACL web tempat aturan ditentukan. Untuk informasi selengkapnya, lihat [AWS WAF aturan](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rules.html). Contoh berikut menunjukkan cara mendefinisikan dan mengaitkan aturan yang berguna untuk melindungi AppSync API.

**Example aturan ACL web untuk membatasi ukuran badan permintaan**  
Berikut ini adalah contoh aturan yang membatasi ukuran badan permintaan. Ini akan dimasukkan ke dalam **editor Rule JSON** saat membuat ACL web di Konsol. AWS WAF   

```
{
    "Name": "BodySizeRule", 
    "Priority": 1, 
    "Action": {
        "Block": {}
    }, 
    "Statement": {
        "SizeConstraintStatement": {
            "ComparisonOperator": "GE",
            "FieldToMatch": {
                "Body": {}
            },
            "Size": 1024, 
            "TextTransformations": [
                {
                    "Priority": 0, 
                    "Type": "NONE"
                }
             ]
          }
       }, 
       "VisibilityConfig": {
           "CloudWatchMetricsEnabled": true, 
           "MetricName": "BodySizeRule", 
           "SampledRequestsEnabled": true
        }
}
```
Setelah Anda membuat ACL web menggunakan aturan contoh sebelumnya, Anda harus mengaitkannya dengan API Anda. AppSync Sebagai alternatif untuk menggunakan Konsol Manajemen AWS, Anda dapat melakukan langkah ini AWS CLI dengan menjalankan perintah berikut.  

```
aws waf associate-web-acl --web-acl-id waf-web-acl-arn --resource-arn appsync-api-arn
```
Diperlukan beberapa menit agar perubahan menyebar, tetapi setelah menjalankan perintah ini, permintaan yang berisi badan yang lebih besar dari 1024 byte akan ditolak oleh. AWS AppSync  
Setelah Anda membuat ACL web baru di AWS WAF Konsol, diperlukan beberapa menit agar ACL web tersedia untuk diasosiasikan dengan API. Jika Anda menjalankan perintah CLI dan mendapatkan `WAFUnavailableEntityException` kesalahan, tunggu beberapa menit dan coba lagi menjalankan perintah.

**Example aturan ACL web untuk membatasi permintaan dari satu alamat IP**  
Berikut ini adalah contoh aturan yang membatasi AppSync API ke 100 permintaan dari satu alamat IP. Ini akan dimasukkan ke dalam **editor Rule JSON** saat membuat ACL web dengan aturan berbasis tarif di Konsol. AWS WAF   

```
{
  "Name": "Throttle",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "Throttle"
  },
  "Statement": {
    "RateBasedStatement": {
      "Limit": 100,
      "AggregateKeyType": "IP"
    }
  }
}
```
Setelah Anda membuat ACL web menggunakan aturan contoh sebelumnya, Anda harus mengaitkannya dengan API Anda. AppSync Anda dapat melakukan langkah ini AWS CLI dengan menjalankan perintah berikut.  

```
aws waf associate-web-acl --web-acl-id waf-web-acl-arn --resource-arn appsync-api-arn
```

**Example aturan ACL web untuk mencegah kueri introspeksi GraphQL \$1\$1schema ke API**  
Berikut ini adalah contoh aturan yang mencegah kueri introspeksi GraphQL \$1\$1schema ke API. Setiap badan HTTP yang menyertakan string “\$1\$1schema” akan diblokir. Ini akan dimasukkan ke dalam **editor Rule JSON** saat membuat ACL web di Konsol. AWS WAF   

```
{
  "Name": "BodyRule",
  "Priority": 5,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "BodyRule"
  },
  "Statement": {
    "ByteMatchStatement": {
      "FieldToMatch": {
        "Body": {}
      },
      "PositionalConstraint": "CONTAINS",
      "SearchString": "__schema",
      "TextTransformations": [
        {
          "Type": "NONE",
          "Priority": 0
        }
      ]
    }
  }
}
```
Setelah Anda membuat ACL web menggunakan aturan contoh sebelumnya, Anda harus mengaitkannya dengan API Anda. AppSync Anda dapat melakukan langkah ini AWS CLI dengan menjalankan perintah berikut.  

```
aws waf associate-web-acl --web-acl-id waf-web-acl-arn --resource-arn appsync-api-arn
```