Skip to content

How do I create and configure Lambda authorizers in API Gateway for authentication and data passing?

5 minute read
0

I want to pass data between Amazon API Gateway, AWS Lambda authorizers, and backend services. Also, I want to handle request data access limitations in authorizers.

Resolution

Note: Make sure that you turn on Amazon CloudWatch execution logs with data tracing. Also, deploy your API after you change the integration or mapping templates.

Create a Lambda authorizer in API Gateway

Prerequisite: Create a Lambda function. For Python instructions, see Building Lambda functions with Python. For Node.js instructions, see Building Lambda functions with Node.js.

Create a REQUEST Lambda authorizer. For Identity source type, make sure that you keep it as Header. For Key, enter a name for your key, such as Authorizationtoken.

Configure your Lambda authorizer and access the request body

Request authorizers can access only headers, query parameters, stage variables, and context variables. In API Gateway, request body data doesn't pass to authorizer functions. To access the request body, configure your Lambda authorizer and use HTTP headers or query string parameters to send the data required for authorization.

Complete the following steps:

  1. Open the API Gateway console.

  2. Select your API, and then select your resource.

  3. Under Methods, select your method, and then configure your Lambda authorizer.
    Note: When you configure your authorizer, header names must be in lower case.

  4. Example code for a Lambda authorizer:

    exports.handler = async (event) => {
      console.log('Authorizer event:', JSON.stringify(event, null, 2));
      const headers = event.headers || {};
      const queryParams = event.queryStringParameters || {};
      const requestContext = event.requestContext || {};
      evaluation_logic_returned_policy
      return {
        principalId: 'user',
        policyDocument: {
          Version: '2012-10-17',
          Statement: [{
            Action: 'execute-api:Invoke',
            Effect: 'Allow',
            Resource: event.methodArn
          }]
        },
        context: {
          userId: '123',
          headerData: headers['validation-data-via-header'] || 'no-header-data',
          queryData: queryParams.validationData || 'no-query-data',
          contextresourcePath: requestContext.resourcePath || 'no-context-resource-path'
        }
      };
    };

    Note: The example code shows an authorizer that has access to client data sent through the headers and query parameters. The authorizer uses the client data to evaluate the access authorization. Also, the example code allows all requests. To return a different policy, replace evaluation_logic_returned_policy with your evaluation logic.

  5. Run the following command to send information to the API and test the authorizer access.

    curl -i -X POST "https://api-id.execute-api.region.amazonaws.com/stage_name/resource_path?validationData=test-query-value"  \
        -H "Authorizationtoken: allow"  -H "Validation-Data-Via-Header: test-header-value"  \
        -H "Content-Type: application/json"  \
        --data '{"test":"data"}'

    Note: Replace api-id with your API ID, region with your AWS Region, stage_name your API stage name, and resource_path with the path for your API. Also, if you entered a different name for your key, then replace Authorizationtoken with the name of your key.

  6. Check your Lambda function or API Gateway logs to confirm that your authorizer has access.

For more information, see Output from an API Gateway Lambda authorizer.

Use a Lambda or HTTP integration to access context to backend services

When your authorizer returns context information, you might not have access to the context information in your backend services. If you don't have access, then you must use a Lambda or HTTP integration as your backend.

Use a Lambda function with a proxy integration

If you use a Lambda function with a proxy integration, then the event that your Lambda function gets automatically adds context data.

Example event:

{
    "httpMethod": "POST",
    "headers": {
        ...
    },
    ...
    "requestContext": {
        "resourceId": "o8nevr",
        "authorizer": {

            "principalId": "user",
            "integrationLatency": 348,

        },
        ...
    },
    "body": "{\"test\":\"data\"}",
    ...
}

Use a Lambda function with a non-proxy integration

If you use a Lambda function with a non-proxy integration, then you must use a mapping template. The mapping template includes the context information in the payload sent to the Lambda function.

To use a mapping template, complete the following steps:

  1. Open the API Gateway console.

  2. Select your API, and then select your resource.

  3. Under Methods, select your method, and then choose Integration request.

  4. Under Mapping templates, add content-type: application/json, and then enter the following template:

    {
        "body": $input.json('$'),
        "authorizer-context": {
            "context-key": "$context.authorizer.context-key"
        }
    }

    Note: Replace context-key with the name that you want for your context key.

Use an HTTP integration with a proxy integration

If you use a proxy integration, then you must use headers or query string parameters in the integration request to include the context information.

Complete the following steps:

  1. Open the API Gateway console.
  2. Select your API, and then select your resource.
  3. Under Methods, select your method.
  4. Choose Integration request, and then choose Edit.
  5. Under URL query string parameters, select Add query string parameter.
  6. For Name, enter header-with-context-information.
  7. For Mapped from, enter context.authorizer.context-key.
    Note: Replace context-key with your context key's name.
  8. Choose Save.

Your HTTP backend adds the context information to the headers or query string parameters based on the section that you added the context information to in your integration.

Use an HTTP integration with a non-proxy integration

If you use a non-proxy integration, then you must add either a header or query string parameters. Or, use a mapping template. For instructions on how to add a header or query string parameters, see the Configure your Lambda authorizer and access the request body section of this article. For instructions on how to use a mapping template, see the Use a Lambda function with a non-proxy integration section of this article.