Controlla l'accesso alle API HTTP con AWS Lambda gli autorizzatori - Amazon API Gateway

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Controlla l'accesso alle API HTTP con AWS Lambda gli autorizzatori

Si sfrutta un'autorizzazione Lambda al fine di utilizzare una funzione Lambda per controllare l'accesso all'API HTTP. Quindi, quando un client invoca un'API, API Gateway richiama la funzione Lambda. API Gateway utilizza la risposta dalla funzione Lambda per determinare se il client può accedere all'API.

Tipo di formato payload

Il tipo di formato del payload dell'autorizzazione specifica il formato dei dati che API Gateway invia a un'autorizzazione Lambda e il modo in cui API Gateway interpreta la risposta ricevuta da Lambda. Se non specifichi una versione del formato di payload, AWS Management Console utilizza la versione più recente per impostazione predefinita. Se crei un autorizzatore Lambda utilizzando AWS CLI, o un SDK AWS CloudFormation, devi specificare un. authorizerPayloadFormatVersion I valori supportati sono 1.0 e 2.0.

Se è necessario garantire la compatibilità con le API REST, utilizzare la versione 1.0.

Gli esempi seguenti mostrano la struttura di ogni tipo di formato 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" } }

Formato della risposta dell'autorizzazione

Il tipo di formato del payload determina anche la struttura della risposta che deve essere restituita dalla funzione Lambda.

Risposta della funzione Lambda per il formato 1.0

Se si sceglie il tipo di formato 1.0, le autorizzazioni Lambda devono restituire una policy IAM che consenta o rifiuti l'accesso alla route dell'API. Nella policy è possibile utilizzare la sintassi standard delle policy IAM. Per alcuni esempi di policy IAM, consultare Controllo degli accessi per invocare un'API. È possibile passare le proprietà del contesto alle integrazioni Lambda o ai log di accesso utilizzando $context.authorizer.property. L'oggetto context è facoltativo e claims è un segnaposto riservato che non può essere utilizzato come oggetto contesto. Per ulteriori informazioni, consulta Personalizzazione dei log di accesso all'API HTTP.

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

Risposta della funzione Lambda per il formato 2.0

Se si sceglie il tipo di formato 2.0, dalla funzione Lambda è possibile restituire un valore booleano o una policy IAM che utilizza la sintassi standard della policy di IAM. Per restituire un valore booleano, abilitare risposte semplici per l'autorizzazione. Negli esempi seguenti viene illustrato il formato in cui è necessario codificare il risultato restituito dalla funzione Lambda. L'oggetto context è facoltativo. È possibile passare le proprietà del contesto alle integrazioni Lambda o ai log di accesso utilizzando $context.authorizer.property. Per ulteriori informazioni, consulta Personalizzazione dei log di accesso all'API HTTP.

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

Esempio di funzioni di autorizzazione Lambda

Le seguenti funzioni Lambda Node.js di esempio illustrano i formati di risposta richiesti che è necessario restituire dalla funzione Lambda per il tipo di formato del 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

Origini di identità

È facoltativamente possibile specificare le origini di identità per un'autorizzazione Lambda. Le origini di identità specificano la posizione dei dati necessari per autorizzare una richiesta. Ad esempio, è possibile specificare i valori di intestazione o di stringa di query come origini di identità. Se si specificano le origini di identità, i client devono includerle nella richiesta. Se la richiesta del client non include le origini di identità, API Gateway non richiama l'autorizzazione Lambda e il client riceve un errore 401. Sono supportate le seguenti origini di identità:

Espressioni di selezione
Tipo Esempio Note
Valore intestazione $request.header.name I nomi delle intestazioni non fanno distinzione tra maiuscole e minuscole.
Valore della stringa di query $request.querystring.name I nomi delle stringhe di query fanno distinzione tra maiuscole e minuscole.
Variabile di contesto $context.variableName Valore di una variabile di contesto supportata.
Variabile di fase $stageVariables.variableName Il valore di una variabile di fase.

Caching delle risposte delle autorizzazioni

Puoi abilitare la memorizzazione nella cache per un autorizzatore Lambda specificando un. authorizerResultTtlInSeconds Quando il caching è abilitato per un'autorizzazione, API Gateway utilizza le origini di identità dell'autorizzazione come chiave della cache. Se un client specifica gli stessi parametri nelle origini di identità all'interno del TTL configurato, API Gateway utilizza il risultato dell'autorizzazione memorizzato nella cache, anziché richiamare la funzione Lambda.

Per abilitare il caching, l'autorizzazione deve disporre di almeno un'origine di identità.

Se si abilitano risposte semplici per un'autorizzazione, la risposta dell'autorizzazione consente o rifiuta completamente tutte le richieste API che corrispondono ai valori dell'origine di identità memorizzata nella cache. Per autorizzazioni più granulari, disabilitare le risposte semplici e restituire una policy IAM.

Per impostazione predefinita, API Gateway utilizza la risposta dell'autorizzazione memorizzata nella cache per tutte le route dell'API che utilizzano l'autorizzazione. Per inserire nella cache le risposte per l'instradamento, aggiungere $context.routeKey alle origini di identità dell'autorizzazione.

Creare un'autorizzazione Lambda

Quando si crea un'autorizzazione Lambda, si specifica la funzione Lambda che API Gateway deve utilizzare. È necessario concedere ad API Gateway l'autorizzazione per richiamare la funzione Lambda utilizzando la policy basata su risorse della funzione o un ruolo IAM. In questo esempio si aggiorna la policy basata su risorse per la funzione in modo che conceda ad API Gateway l'autorizzazione per richiamare la funzione Lambda.

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

Il comando seguente concede ad API Gateway l'autorizzazione per richiamare la funzione Lambda. Se l'API Gateway non dispone dell'autorizzazione a richiamare la funzione, i client ricevono un errore 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"

Dopo aver creato un'autorizzazione e concesso ad API Gateway l'autorizzazione per richiamarla, aggiornare la route affinché utilizzi l'autorizzazione.

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

Risoluzione dei problemi relativi alle autorizzazioni Lambda

Se l'API Gateway non è in grado di richiamare l'autorizzazione Lambda o l'autorizzazione Lambda restituisce una risposta in un formato non valido, i client ricevono una risposta 500 Internal Server Error.

Per risolvere gli errori, abilitare la registrazione degli accessi per la fase dell'API. Includere la variabile di registrazione $context.authorizer.error nel formato di log.

Se i log indicano che API Gateway non dispone dell'autorizzazione per richiamare la funzione, aggiornare la policy basata su risorse della funzione o fornire un ruolo IAM per concedere ad API Gateway il permesso di per richiamare l'autorizzazione.

Se i log indicano che la funzione Lambda restituisce una risposta non valida, verificare che la funzione Lambda restituisca una risposta nel formato richiesto.