Kontrol akses ke HTTP APIs dengan AWS Lambda otorisasi - APIGerbang Amazon

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

Kontrol akses ke HTTP APIs dengan AWS Lambda otorisasi

Anda menggunakan Lambda Authorizer untuk menggunakan fungsi Lambda untuk mengontrol akses ke Anda. HTTP API Kemudian, ketika klien memanggil AndaAPI, API Gateway memanggil fungsi Lambda Anda. APIGateway menggunakan respons dari fungsi Lambda Anda untuk menentukan apakah klien dapat mengakses Anda. API

Versi format payload

Versi format payload authorizer menentukan format data yang dikirim API Gateway ke otorisasi Lambda, dan bagaimana Gateway API menafsirkan respons dari Lambda. Jika Anda tidak menentukan versi format payload, akan AWS Management Console menggunakan versi terbaru secara default. Jika Anda membuat otorisasi Lambda dengan menggunakan AWS CLI,, atau AWS CloudFormation SDK, Anda harus menentukan. authorizerPayloadFormatVersion Nilai yang di-support adalah 1.0 dan 2.0.

Jika Anda membutuhkan kompatibilitas dengan RESTAPIs, gunakan versi1.0.

Contoh berikut menunjukkan struktur setiap versi format payload.

2.0
{ "version": "2.0", "type": "REQUEST", "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", "identitySource": ["user1", "123"], "routeKey": "$default", "rawPath": "/my/path", "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value", "cookies": ["cookie1", "cookie2"], "headers": { "header1": "value1", "header2": "value2" }, "queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" }, "requestContext": { "accountId": "123456789012", "apiId": "api-id", "authentication": { "clientCert": { "clientCertPem": "CERT_CONTENT", "subjectDN": "www.example.com", "issuerDN": "Example issuer", "serialNumber": "1", "validity": { "notBefore": "May 28 12:30:02 2019 GMT", "notAfter": "Aug 5 09:36:04 2021 GMT" } } }, "domainName": "id.execute-api.us-east-1.amazonaws.com", "domainPrefix": "id", "http": { "method": "POST", "path": "/my/path", "protocol": "HTTP/1.1", "sourceIp": "IP", "userAgent": "agent" }, "requestId": "id", "routeKey": "$default", "stage": "$default", "time": "12/Mar/2020:19:03:58 +0000", "timeEpoch": 1583348638390 }, "pathParameters": { "parameter1": "value1" }, "stageVariables": { "stageVariable1": "value1", "stageVariable2": "value2" } }
1.0
{ "version": "1.0", "type": "REQUEST", "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", "identitySource": "user1,123", "authorizationToken": "user1,123", "resource": "/request", "path": "/request", "httpMethod": "GET", "headers": { "X-AMZ-Date": "20170718T062915Z", "Accept": "*/*", "HeaderAuth1": "headerValue1", "CloudFront-Viewer-Country": "US", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Is-Mobile-Viewer": "false", "User-Agent": "..." }, "queryStringParameters": { "QueryString1": "queryValue1" }, "pathParameters": {}, "stageVariables": { "StageVar1": "stageValue1" }, "requestContext": { "path": "/request", "accountId": "123456789012", "resourceId": "05c7jb", "stage": "test", "requestId": "...", "identity": { "apiKey": "...", "sourceIp": "...", "clientCert": { "clientCertPem": "CERT_CONTENT", "subjectDN": "www.example.com", "issuerDN": "Example issuer", "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", "validity": { "notBefore": "May 28 12:30:02 2019 GMT", "notAfter": "Aug 5 09:36:04 2021 GMT" } } }, "resourcePath": "/request", "httpMethod": "GET", "apiId": "abcdef123" } }

Format respons otorisasi Lambda

Versi format payload juga menentukan struktur respons yang harus Anda kembalikan dari fungsi Lambda Anda.

Respons fungsi Lambda untuk format 1.0

Jika Anda memilih versi 1.0 format, otorisasi Lambda harus mengembalikan IAM kebijakan yang mengizinkan atau menolak akses ke rute Anda. API Anda dapat menggunakan sintaks IAM kebijakan standar dalam kebijakan. Untuk contoh IAM kebijakan, lihatKontrol akses untuk memanggil API. Anda dapat meneruskan properti konteks ke integrasi Lambda atau mengakses log dengan menggunakan. $context.authorizer.property contextObjek adalah opsional dan claims merupakan placeholder yang dicadangkan dan tidak dapat digunakan sebagai objek konteks. Untuk mempelajari selengkapnya, lihat Sesuaikan log HTTP API akses.

{ "principalId": "abcdef", // The principal user identification associated with the token sent by the client. "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow|Deny", "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]" } ] }, "context": { "exampleKey": "exampleValue" } }

Respons fungsi Lambda untuk format 2.0

Jika memilih versi 2.0 format, Anda dapat menampilkan nilai Boolean atau IAM kebijakan yang menggunakan sintaks IAM kebijakan standar dari fungsi Lambda Anda. Untuk mengembalikan nilai Boolean, aktifkan tanggapan sederhana untuk otorisasi. Contoh berikut menunjukkan format yang harus Anda kodekan fungsi Lambda Anda untuk kembali. contextObjeknya opsional. Anda dapat meneruskan properti konteks ke integrasi Lambda atau mengakses log dengan menggunakan. $context.authorizer.property Untuk mempelajari selengkapnya, lihat Sesuaikan log HTTP API akses.

Simple response
{ "isAuthorized": true/false, "context": { "exampleKey": "exampleValue" } }
IAM policy
{ "principalId": "abcdef", // The principal user identification associated with the token sent by the client. "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow|Deny", "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]" } ] }, "context": { "exampleKey": "exampleValue" } }

Contoh fungsi otorisasi Lambda

Contoh berikut fungsi Lambda Node.js menunjukkan format respons yang diperlukan yang perlu Anda kembalikan dari fungsi Lambda Anda untuk versi format payload. 2.0

Simple response - Node.js
export const handler = async(event) => { let response = { "isAuthorized": false, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": true, "arrayKey": ["value1", "value2"], "mapKey": {"value1": "value2"} } }; if (event.headers.authorization === "secretToken") { console.log("allowed"); response = { "isAuthorized": true, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": true, "arrayKey": ["value1", "value2"], "mapKey": {"value1": "value2"} } }; } return response; };
Simple response - Python
import json def lambda_handler(event, context): response = { "isAuthorized": False, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": True, "arrayKey": ["value1", "value2"], "mapKey": {"value1": "value2"} } } try: if (event["headers"]["authorization"] == "secretToken"): response = { "isAuthorized": True, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": True, "arrayKey": ["value1", "value2"], "mapKey": {"value1": "value2"} } } print('allowed') return response else: print('denied') return response except BaseException: print('denied') return response
IAM policy - Node.js
export const handler = async(event) => { if (event.headers.authorization == "secretToken") { console.log("allowed"); return { "principalId": "abcdef", // The principal user identification associated with the token sent by the client. "policyDocument": { "Version": "2012-10-17", "Statement": [{ "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": event.routeArn }] }, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": true, "arrayKey": ["value1", "value2"], "mapKey": { "value1": "value2" } } }; } else { console.log("denied"); return { "principalId": "abcdef", // The principal user identification associated with the token sent by the client. "policyDocument": { "Version": "2012-10-17", "Statement": [{ "Action": "execute-api:Invoke", "Effect": "Deny", "Resource": event.routeArn }] }, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": true, "arrayKey": ["value1", "value2"], "mapKey": { "value1": "value2" } } }; } };
IAM policy - Python
import json def lambda_handler(event, context): response = { # The principal user identification associated with the token sent by # the client. "principalId": "abcdef", "policyDocument": { "Version": "2012-10-17", "Statement": [{ "Action": "execute-api:Invoke", "Effect": "Deny", "Resource": event["routeArn"] }] }, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": True, "arrayKey": ["value1", "value2"], "mapKey": {"value1": "value2"} } } try: if (event["headers"]["authorization"] == "secretToken"): response = { # The principal user identification associated with the token # sent by the client. "principalId": "abcdef", "policyDocument": { "Version": "2012-10-17", "Statement": [{ "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": event["routeArn"] }] }, "context": { "stringKey": "value", "numberKey": 1, "booleanKey": True, "arrayKey": ["value1", "value2"], "mapKey": {"value1": "value2"} } } print('allowed') return response else: print('denied') return response except BaseException: print('denied') return response

Sumber identitas

Anda dapat secara opsional menentukan sumber identitas untuk otorisasi Lambda. Sumber identitas menentukan lokasi data yang diperlukan untuk mengotorisasi permintaan. Misalnya, Anda dapat menentukan nilai string header atau kueri sebagai sumber identitas. Jika Anda menentukan sumber identitas, klien harus memasukkannya dalam permintaan. Jika permintaan klien tidak menyertakan sumber identitas, API Gateway tidak memanggil otorisasi Lambda Anda, dan klien menerima kesalahan. 401

Tabel berikut menjelaskan sumber identitas yang didukung untuk otorisasi Lambda.

Jenis

Contoh

Catatan

Nilai header $ request.header.name Nama header tidak peka huruf besar/kecil.
Nilai string kueri $request.querystring.name Nama string kueri peka huruf besar/kecil.
Variabel konteks $ konteks.variableName Nilai variabel konteks yang didukung.
Variabel tahap $stageVariables.variableName Nilai variabel tahap.

Tanggapan otorisasi cache

Anda dapat mengaktifkan caching untuk otorisasi Lambda dengan menentukan file. authorizerResultTtlInSeconds Saat caching diaktifkan untuk otorisasi, API Gateway menggunakan sumber identitas otorisasi sebagai kunci cache. Jika klien menentukan parameter yang sama dalam sumber identitas dalam konfigurasiTTL, API Gateway menggunakan hasil otorisasi cache, daripada menjalankan fungsi Lambda Anda.

Untuk mengaktifkan caching, otorisasi Anda harus memiliki setidaknya satu sumber identitas.

Jika Anda mengaktifkan respons sederhana untuk otorisasi, respons otorisasi sepenuhnya mengizinkan atau menolak semua API permintaan yang cocok dengan nilai sumber identitas cache. Untuk izin yang lebih terperinci, nonaktifkan respons sederhana dan kembalikan kebijakan. IAM

Secara default, API Gateway menggunakan respon authorizer cache untuk semua rute API yang menggunakan authorizer. Untuk menyimpan respons per rute, tambahkan $context.routeKey ke sumber identitas otorisasi Anda.

Buat Authorizer Lambda

Saat Anda membuat otorisasi Lambda, Anda menentukan fungsi Lambda untuk digunakan Gateway. API Anda harus memberikan izin API Gateway untuk menjalankan fungsi Lambda dengan menggunakan kebijakan sumber daya fungsi atau IAM peran. Untuk contoh ini, kami memperbarui kebijakan sumber daya untuk fungsi tersebut sehingga memberikan izin API Gateway untuk menjalankan fungsi Lambda kami.

aws apigatewayv2 create-authorizer \ --api-id abcdef123 \ --authorizer-type REQUEST \ --identity-source '$request.header.Authorization' \ --name lambda-authorizer \ --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:my-function/invocations' \ --authorizer-payload-format-version '2.0' \ --enable-simple-responses

Perintah berikut memberikan izin API Gateway untuk menjalankan fungsi Lambda Anda. Jika API Gateway tidak memiliki izin untuk menjalankan fungsi Anda, klien akan menerima file. 500 Internal Server Error

aws lambda add-permission \ --function-name my-authorizer-function \ --statement-id apigateway-invoke-permissions-abc123 \ --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn "arn:aws:execute-api:us-west-2:123456789012:api-id/authorizers/authorizer-id"

Setelah Anda membuat otorisasi dan memberikan izin API Gateway untuk memanggilnya, perbarui rute Anda untuk menggunakan otorisasi.

aws apigatewayv2 update-route \ --api-id abcdef123 \ --route-id acd123 \ --authorization-type CUSTOM \ --authorizer-id def123

Memecahkan masalah otorisasi Lambda

Jika API Gateway tidak dapat memanggil otorisasi Lambda Anda, atau otorisasi Lambda Anda mengembalikan respons dalam format yang tidak valid, klien menerima file. 500 Internal Server Error

Untuk memecahkan masalah kesalahan, aktifkan pencatatan akses untuk panggung AndaAPI. Sertakan variabel $context.authorizer.error logging dalam format log Anda.

Jika log menunjukkan bahwa API Gateway tidak memiliki izin untuk memanggil fungsi Anda, perbarui kebijakan sumber daya fungsi Anda atau berikan IAM peran untuk memberikan izin API Gateway untuk memanggil otorisasi Anda.

Jika log menunjukkan bahwa fungsi Lambda Anda mengembalikan respons yang tidak valid, verifikasi bahwa fungsi Lambda Anda mengembalikan respons dalam format yang diperlukan.