Uso di autorizzazioni Lambda di API Gateway - 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à.

Uso di autorizzazioni Lambda di API Gateway

Usa un autorizzatore Lambda (precedentemente noto come autorizzatore personalizzato) per controllare l'accesso alla tua API. Quando un client richiede il metodo della tua API, API Gateway chiama l'autorizzatore Lambda. L'autorizzatore Lambda accetta l'identità del chiamante come input e restituisce una policy IAM come output.

Usa un autorizzatore Lambda per implementare uno schema di autorizzazione personalizzato. Lo schema può utilizzare i parametri di richiesta per determinare l'identità del chiamante o utilizzare una strategia di autenticazione con token portatore come OAuth o SAML. Crea un autorizzatore Lambda nella console API REST di API Gateway, utilizzando o un AWS CLI SDK. AWS

Flusso di lavoro di autorizzazione Lambda

Il diagramma seguente mostra il flusso di lavoro di autorizzazione per un autorizzatore Lambda.

Flusso di lavoro per le autorizzazioni Lambda di API Gateway
Flusso di lavoro per le autorizzazioni Lambda di API Gateway
  1. Il client chiama un metodo su un'API API Gateway, passando un token bearer o parametri di richiesta.

  2. API Gateway verifica se la richiesta del metodo è configurata con un autorizzatore Lambda. In tal caso, API Gateway chiama la funzione Lambda.

  3. La funzione Lambda autentica il chiamante. La funzione può autenticarsi nei seguenti modi:

    • Chiamando un provider OAuth per ottenere un token di accesso OAuth.

    • Chiamando un provider SAML per ottenere un'asserzione SAML.

    • Generando una policy IAM basata sui valori dei parametri di richiesta.

    • Recuperando le credenziali da un database.

  4. La funzione Lambda restituisce una policy IAM e un identificatore principale. Se la funzione Lambda non restituisce tali informazioni, la chiamata ha esito negativo.

  5. API Gateway valuta la policy IAM.

    • Se l'accesso viene negato, API Gateway restituisce un codice di stato HTTP appropriato, ad esempio 403 ACCESS_DENIED.

    • Se l'accesso è consentito, API Gateway richiama il metodo.

      Se abiliti la memorizzazione nella cache delle autorizzazioni, API Gateway memorizza nella cache la policy in modo che la funzione di autorizzazione Lambda non venga richiamata nuovamente.

È possibile personalizzare le risposte o le risposte del gateway. 403 ACCESS_DENIED 401 UNAUTHORIZED Per ulteriori informazioni, consulta Risposte gateway per le API REST in API Gateway.

Scelta di un tipo di autorizzatore Lambda

Esistono due tipi di autorizzazioni Lambda:

Richiedi l'autorizzazione Lambda basata su parametri (authorizer) REQUEST

Un REQUEST autorizzatore riceve l'identità del chiamante in una combinazione di intestazioni, parametri della stringa di query e variabili. stageVariables$context È possibile utilizzare un programma di REQUEST autorizzazione per creare politiche dettagliate basate sulle informazioni provenienti da più fonti di identità, come le variabili e di contesto. $context.path $context.httpMethod

Se attivi la memorizzazione nella cache delle autorizzazioni per un REQUEST autorizzatore, API Gateway verifica che tutte le fonti di identità specificate siano presenti nella richiesta. Se una fonte di identificazione specificata è mancante, nulla o vuota, API Gateway restituisce una risposta 401 Unauthorized HTTP senza chiamare la funzione di autorizzazione Lambda. Quando vengono definite più fonti di identità, queste vengono tutte utilizzate per derivare la chiave della cache dell'autorizzatore, mantenendo l'ordine. È possibile definire una chiave di cache dettagliata utilizzando più fonti di identità.

Se modificate una qualsiasi delle parti chiave della cache e ridistribuite l'API, l'autorizzatore scarta il documento di policy memorizzato nella cache e ne genera uno nuovo.

Se disattivi la memorizzazione nella cache delle autorizzazioni per un REQUEST autorizzatore, API Gateway passa direttamente la richiesta alla funzione Lambda.

Autorizzatore Lambda basato su token (autorizzatore) TOKEN

Un TOKEN autorizzatore riceve l'identità del chiamante in un token portante, ad esempio un token Web JSON (JWT) o un token OAuth.

Se si attiva la memorizzazione nella cache delle autorizzazioni per un TOKEN autorizzatore, il nome dell'intestazione specificato nella fonte del token diventa la chiave della cache.

Inoltre, puoi utilizzare la convalida dei token per inserire una dichiarazione. RegEx API Gateway esegue la convalida iniziale del token di input rispetto a questa espressione e richiama la funzione di autorizzazione Lambda in caso di convalida riuscita. Ciò aiuta a ridurre le chiamate all'API.

La IdentityValidationExpression proprietà è supportata solo per gli autorizzatori. TOKEN Per ulteriori informazioni, consulta x-amazon-apigateway-authorizer oggetto.

Nota

Ti consigliamo di utilizzare un REQUEST autorizzatore per controllare l'accesso alla tua API. Puoi controllare l'accesso alla tua API in base a più fonti di identità quando usi un REQUEST autorizzatore, rispetto a una singola fonte di identità quando usi un TOKEN autorizzatore. Inoltre, puoi separare le chiavi della cache utilizzando più fonti di identità per un REQUEST autorizzatore.

Esempio di funzione Lambda REQUEST dell'autorizzatore

Il codice di esempio seguente crea una funzione di autorizzazione Lambda che consente una richiesta se l'HeaderAuth1intestazione, il parametro di QueryString1 query e la variabile stage forniti dal client corrispondono StageVar1 tutti ai valori specificati di, e, rispettivamente. headerValue1 queryValue1 stageValue1

Node.js
// A simple request-based authorizer example to demonstrate how to use request // parameters to allow or deny a request. In this example, a request is // authorized if the client-supplied HeaderAuth1 header, QueryString1 // query parameter, and stage variable of StageVar1 all match // specified values of 'headerValue1', 'queryValue1', and 'stageValue1', // respectively. export const handler = function(event, context, callback) { console.log('Received event:', JSON.stringify(event, null, 2)); // Retrieve request parameters from the Lambda function input: var headers = event.headers; var queryStringParameters = event.queryStringParameters; var pathParameters = event.pathParameters; var stageVariables = event.stageVariables; // Parse the input for the parameter values var tmp = event.methodArn.split(':'); var apiGatewayArnTmp = tmp[5].split('/'); var awsAccountId = tmp[4]; var region = tmp[3]; var restApiId = apiGatewayArnTmp[0]; var stage = apiGatewayArnTmp[1]; var method = apiGatewayArnTmp[2]; var resource = '/'; // root resource if (apiGatewayArnTmp[3]) { resource += apiGatewayArnTmp[3]; } // Perform authorization to return the Allow policy for correct parameters and // the 'Unauthorized' error, otherwise. var authResponse = {}; var condition = {}; condition.IpAddress = {}; if (headers.HeaderAuth1 === "headerValue1" && queryStringParameters.QueryString1 === "queryValue1" && stageVariables.StageVar1 === "stageValue1") { callback(null, generateAllow('me', event.methodArn)); } else { callback("Unauthorized"); } } // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { // Required output: var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; // default version policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; // default action statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; } // Optional output with custom properties of the String, Number or Boolean type. authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; } var generateAllow = function(principalId, resource) { return generatePolicy(principalId, 'Allow', resource); } var generateDeny = function(principalId, resource) { return generatePolicy(principalId, 'Deny', resource); }
Python
# A simple request-based authorizer example to demonstrate how to use request # parameters to allow or deny a request. In this example, a request is # authorized if the client-supplied HeaderAuth1 header, QueryString1 # query parameter, and stage variable of StageVar1 all match # specified values of 'headerValue1', 'queryValue1', and 'stageValue1', # respectively. import json def lambda_handler(event, context): print(event) # Retrieve request parameters from the Lambda function input: headers = event['headers'] queryStringParameters = event['queryStringParameters'] pathParameters = event['pathParameters'] stageVariables = event['stageVariables'] # Parse the input for the parameter values tmp = event['methodArn'].split(':') apiGatewayArnTmp = tmp[5].split('/') awsAccountId = tmp[4] region = tmp[3] restApiId = apiGatewayArnTmp[0] stage = apiGatewayArnTmp[1] method = apiGatewayArnTmp[2] resource = '/' if (apiGatewayArnTmp[3]): resource += apiGatewayArnTmp[3] # Perform authorization to return the Allow policy for correct parameters # and the 'Unauthorized' error, otherwise. authResponse = {} condition = {} condition['IpAddress'] = {} if (headers['HeaderAuth1'] == "headerValue1" and queryStringParameters['QueryString1'] == "queryValue1" and stageVariables['StageVar1'] == "stageValue1"): response = generateAllow('me', event['methodArn']) print('authorized') return json.loads(response) else: print('unauthorized') raise Exception('Unauthorized') # Return a 401 Unauthorized response return 'unauthorized' # Help function to generate IAM policy def generatePolicy(principalId, effect, resource): authResponse = {} authResponse['principalId'] = principalId if (effect and resource): policyDocument = {} policyDocument['Version'] = '2012-10-17' policyDocument['Statement'] = [] statementOne = {} statementOne['Action'] = 'execute-api:Invoke' statementOne['Effect'] = effect statementOne['Resource'] = resource policyDocument['Statement'] = [statementOne] authResponse['policyDocument'] = policyDocument authResponse['context'] = { "stringKey": "stringval", "numberKey": 123, "booleanKey": True } authResponse_JSON = json.dumps(authResponse) return authResponse_JSON def generateAllow(principalId, resource): return generatePolicy(principalId, 'Allow', resource) def generateDeny(principalId, resource): return generatePolicy(principalId, 'Deny', resource)

In questo esempio, la funzione di autorizzazione Lambda controlla i parametri di input e si comporta nel modo seguente:

  • Se tutti i valori dei parametri richiesti corrispondono ai valori previsti, la funzione di autorizzazione restituisce una risposta HTTP 200 OK e una policy IAM simile alla seguente e la richiesta del metodo ha esito positivo:

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
  • In caso contrario, la funzione di autorizzazione restituisce una risposta 401 Unauthorized HTTP e la richiesta del metodo ha esito negativo.

Oltre a restituire una policy IAM, la funzione di autorizzazione Lambda deve restituire anche l'identificatore dell'entità principale dell'intermediario. Facoltativamente, può restituire un context oggetto contenente informazioni aggiuntive che possono essere passate al backend di integrazione. Per ulteriori informazioni, consulta Output da un autorizzatore Lambda API Gateway.

Nel codice di produzione, potrebbe essere necessario autenticare l'utente prima di concedere l'autorizzazione. È possibile aggiungere la logica di autenticazione nella funzione Lambda chiamando un provider di autenticazione come indicato nella documentazione relativa a tale provider.

Esempio di funzione Lambda TOKEN dell'autorizzatore

Il codice di esempio seguente crea una funzione di autorizzazione TOKEN Lambda che consente a un chiamante di richiamare un metodo se il valore del token fornito dal client è. allow Al chiamante non è consentito richiamare la richiesta se il valore del token è. deny Se il valore del token è unauthorized o è una stringa vuota, la funzione di autorizzazione restituisce una risposta. 401 UNAUTHORIZED

Node.js
// A simple token-based authorizer example to demonstrate how to use an authorization token // to allow or deny a request. In this example, the caller named 'user' is allowed to invoke // a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke // the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty // string, the authorizer function returns an HTTP 401 status code. For any other token value, // the authorizer returns an HTTP 500 status code. // Note that token values are case-sensitive. export const handler = function(event, context, callback) { var token = event.authorizationToken; switch (token) { case 'allow': callback(null, generatePolicy('user', 'Allow', event.methodArn)); break; case 'deny': callback(null, generatePolicy('user', 'Deny', event.methodArn)); break; case 'unauthorized': callback("Unauthorized"); // Return a 401 Unauthorized response break; default: callback("Error: Invalid token"); // Return a 500 Invalid token response } }; // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; } // Optional output with custom properties of the String, Number or Boolean type. authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; }
Python
# A simple token-based authorizer example to demonstrate how to use an authorization token # to allow or deny a request. In this example, the caller named 'user' is allowed to invoke # a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke # the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty # string, the authorizer function returns an HTTP 401 status code. For any other token value, # the authorizer returns an HTTP 500 status code. # Note that token values are case-sensitive. import json def lambda_handler(event, context): token = event['authorizationToken'] if token == 'allow': print('authorized') response = generatePolicy('user', 'Allow', event['methodArn']) elif token == 'deny': print('unauthorized') response = generatePolicy('user', 'Deny', event['methodArn']) elif token == 'unauthorized': print('unauthorized') raise Exception('Unauthorized') # Return a 401 Unauthorized response return 'unauthorized' try: return json.loads(response) except BaseException: print('unauthorized') return 'unauthorized' # Return a 500 error def generatePolicy(principalId, effect, resource): authResponse = {} authResponse['principalId'] = principalId if (effect and resource): policyDocument = {} policyDocument['Version'] = '2012-10-17' policyDocument['Statement'] = [] statementOne = {} statementOne['Action'] = 'execute-api:Invoke' statementOne['Effect'] = effect statementOne['Resource'] = resource policyDocument['Statement'] = [statementOne] authResponse['policyDocument'] = policyDocument authResponse['context'] = { "stringKey": "stringval", "numberKey": 123, "booleanKey": True } authResponse_JSON = json.dumps(authResponse) return authResponse_JSON

In questo esempio, quando l'API riceve una richiesta del metodo, API Gateway passa il token di origine alla funzione di autorizzazione Lambda nell'attributo event.authorizationToken. La funzione di autorizzazione Lambda legge il token e si comporta nel modo seguente:

  • Se il valore del token è allow, la funzione di autorizzazione restituisce una risposta HTTP 200 OK e una policy IAM simile alla seguente e la richiesta del metodo ha esito positivo:

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
  • Se il valore del token è deny, la funzione di autorizzazione restituisce una risposta HTTP 200 OK e una policy IAM Deny simile alla seguente e la richiesta del metodo ha esito negativo:

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Deny", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
    Nota

    Al di fuori dell'ambiente di test, API Gateway restituisce una risposta 403 Forbidden HTTP e la richiesta del metodo ha esito negativo.

  • Se il valore del token è unauthorized o una stringa vuota, la funzione del provider di autorizzazione restituisce una risposta HTTP 401 Unauthorized e la chiamata al metodo ha esito negativo.

  • Se il token ha un valore diverso dai precedenti, il client riceve una risposta 500 Invalid token e la chiamata al metodo ha esito negativo.

Oltre a restituire una policy IAM, la funzione di autorizzazione Lambda deve restituire anche l'identificatore dell'entità principale dell'intermediario. Facoltativamente, può restituire un context oggetto contenente informazioni aggiuntive che possono essere passate al backend di integrazione. Per ulteriori informazioni, consulta Output da un autorizzatore Lambda API Gateway.

Nel codice di produzione, potrebbe essere necessario autenticare l'utente prima di concedere l'autorizzazione. È possibile aggiungere la logica di autenticazione nella funzione Lambda chiamando un provider di autenticazione come indicato nella documentazione relativa a tale provider.

Esempi aggiuntivi di funzioni di autorizzazione Lambda

L'elenco seguente mostra altri esempi di funzioni di autorizzazione Lambda. Puoi creare una funzione Lambda nello stesso account o in un account diverso da dove hai creato l'API.

Per l'esempio precedente di funzioni Lambda, puoi utilizzare le funzioni integrate AWSLambdaBasicExecutionRole, poiché queste funzioni non chiamano altri AWS servizi. Se la tua funzione Lambda chiama altri AWS servizi, dovrai assegnare un ruolo di esecuzione IAM alla funzione Lambda. Per creare il ruolo, segui le istruzioni in Ruolo di esecuzione AWS Lambda.

Esempi aggiuntivi di funzioni di autorizzazione Lambda