Creating an API Gateway Lambda Authorizer

Hemny Singh
Chegg
7 min readJan 14, 2020

--

A Lambda authorizer is a feature in API Gateway that controls access to your API. As the name suggests, it uses a Lambda function. It’s useful when you want to write your custom authorization logic using bearer tokens or request parameters to identify the caller and its access. When a user requests your API, API Gateway calls the Lambda authorizer. This Lambda authorizer extracts the bearer token or request parameter from the request, processes it, and returns an Identity and Access Management (IAM) policy. API Gateway evaluates this IAM policy and determines if the request can hit the targeted backend service.

Architecture of API gateway lambda authorizer. Ref: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-u
Fig 1. Architecture diagram of API Gateway Lambda authorizer

Within Chegg, when a user was authenticated on one of the pages, it was also required to keep the authentication on the rest of the system, too. To address this, we wanted an authorization layer that could validate the incoming requests. After exploring a couple of options, we decided to use Lambda authorizer because:

  • The authorization logic will be independent from the rest of the codebase.
  • The response for every unique client can be cached to avoid multiple requests.

There are two types of Lambda authorizer:

  1. Token-based: Lambda authorizer receives a caller’s identity as “bearer token”, such as JWT or OAuth token.
  2. Request parameter-based: Lambda authorizer receives the caller’s identity as a “request” object with headers, query parameters, stageVariables, and $context variables. For WebSocket APIs, only the request parameter-based Lambda authorizer is supported.

How do I create an API Gateway Lambda authorizer?

There are four simple steps to create your custom authorizer:

  1. Create a Lambda function as the custom authorizer.
  2. Create a Lambda function as the end service.
  3. Create the API using API Gateway.
  4. Configure API Gateway with your custom authorizer.

Now, let’s jump on to the detailed explanations of these four steps.

Prerequisite:

Before starting, two prerequisites should be fulfilled:

  1. Access to the Amazon Web Services (AWS) console and being an IAM user with access to S3, Lambda, and API Gateway is required.
  2. Go through the Lambda authorizer blueprints by AWS Labs to get the idea before starting to code. We are using Node.js as the runtime in the example.

Now, let’s start the real work!

1. Create a Lambda function as the authorizer

Set up a Lambda function, which will work as the authorizer. This Lambda function will be triggered when your API is called. The following example is the token-based Lambda authorizer function:

Fig 2. Creating a Lambda function in AWS console

Now, add code for the authorizer. The Lambda authorizer expects a specific JSON input and returns the AWS policy. The Lambda function expects the input in the event parameter, as shown in Figure 3. The sample input is shown below:

{
"type":"TOKEN",
"authorizationToken":"{caller-supplied-token}",
"methodArn":"{arn-of-incoming-request}"
}

Write the logic to authorize the request in the inline code editor, as shown in Figure 3. The code shown is taken from AWS documentation.

Added code for authorizer using lamda’s inline code editor
Fig 3. Inline code editor to add source code in Lambda function

Once the code is added, configure “Runtime” and “Handler”, then click on the Save button. The output of the custom authorizer can also contain a context map containing key-value pairs. You can access the details you need in API Gateway using this context. We’ll see the detailed use case for this later.

Note: Do not use the code shown in this example in your production code. Use an encrypted token as an authorization token.

2. Create a Lambda function as the end service

The API you want to secure will call some web service. This web service can be a Lambda function, endpoints on EC2, or any public API endpoint. We’ll be using Lambda function as an example here.

You need to create a Lambda function, as shown in step one, and write code. Or you can use the default example of Lambda — “Hello from Lambda!” — for testing.

Fig 4. Lambda function that will be called by secured API

3. Create the API using API Gateway

To create your API, go to the API Gateway service and click the Create API button. You can follow the steps shown in Figure 5.

Fig 5. Create API using API Gateway

Now, go to the next page and add a method by selecting Actions → Create Method. Select Get as the method and integrate the Lambda function you created in step two.

Second step: Adding lambda function which will be called by this API
Fig 6. Add method in API and integrate Lambda function

As soon as you click on the Save button, this API will be added as a trigger in your selected Lambda function in Figure 6. Now, deploy the API by clicking on ActionsDeploy API button. Now, you’ll have the Invoke URL as the endpoint of your API to access the Lambda function. You can test your API using Postman or the API Gateway console.

4. Configure API Gateway with your custom authorizer

Navigate to the API Gateway console and select the API you created in step three. Click on Authorizers from the API menu, and click on Create New Authorizer, as shown in Figure 7. You can select the Lambda authorizer function we created in step one by using the Lambda function field.

Fig 7. Add a new authorizer in API Gateway console

You can test this authorizer by clicking on Test. It will open a modal where you can provide your token and test the response from the Lambda authorizer function.

Now, we need to enable this authorizer for your API. Go to Resource Get → Method Request. Select your custom authorizer in Authorization under Settings, as shown in Figure 8.

Fig 8. Select custom authorizer as an Authorization

Once done, deploy the API. Your API is now ready to test. You can test it by using Postman, as shown below:

Fig 9. Testing API using Postman. No token is provided (left) and the correct token (right).

Smooth. But is it enough to build a real-world application?

One important use case we handled was passing some data to the targeted service for authorized requests. The best way to do this is by setting data in Request or Response headers. API Gateway provides the functionality to update these headers. Let’s see how!

Use case

A user requests the Lambda authorizer-protected app. The custom authorizer will read the token and check if the user is authorized or not. If the user is authorized, the request will hit the server. This encrypted token also contains email and user_id, as required by your web service. Since the authorizer already fetched these details while verifying the token, you don’t want your web service to do the same thing. Instead, your API Gateway can set these details in the headers.

Lambda authorizer can pass details fetched from the token (like email and user_id) to API Gateway using context map as we discussed in step one.

To update Request headers, you can follow these steps:

  • Go to the Resources tab in API Gateway and click on the method where you want to add these customized headers.
  • Click on Method Request > HTTP Request Headers and add new headers. An example is EMAIL and USER_ID, as shown in Figure 10. Please note that these headers will be overridden by the authorizer for an authorized request.
Defined HTTP request headers under Method Request -> HTTP Request headers.
Fig 10. Add HTTP Request header using API Gateway console
  • As we want to override Request headers, we need to configure the API Gateway’s request. We can configure it from the Integration Request tab. Please check that Use Lambda Proxy Integration is unchecked. Go to the HTTP headers option and add header EMAIL and USER_ID.
Map the headers you want to override in HTTP Headers under Integration Request section
Fig 11. Map headers with Request header in Integration Request tab
  • Now, go to Mapping Template and select the Request Body Passthrough option: When there are no templates defined (recommended). Add a mapping template for Content-Type as the application/json.
  • Click on the Mapping Template you just added. You will see a text editor where you can write the code to generate the API request, which will be passed to the Lambda function and override the Request header. A mapping template is a script expressed in Velocity Template Language (VTL) and applied to the request payload using JSONPath expressions. You can follow the below example to write the script for the mapping template.
  • Save the template and deploy the API by clicking the Deploy API button under the Actions dropdown.
  • Now, your web service will receive EMAIL and USER_ID in the Request headers.

The drawback of using the above approach is that you cannot use the proxy integration for your API Gateway. It means API requests will not be passed to your Lambda as-it-is. However, this can be done by the mapping template, which provides more control over transmission data.

That’s it! You can now build your own Lambda authorizer with header customizations.

Thank you for reading, and feel free to post your questions and thoughts in the comment section. For similar content, check out more from Chegg Engineering.

--

--