Menu
Amazon API Gateway
Developer Guide

Enable Amazon API Gateway Custom Authorization

Amazon API Gateway Custom Authorization Overview

With Amazon API Gateway custom authorization, you can control access to your APIs using bearer token authentication strategies, such as OAuth or SAML. To do so, you provide and configure a custom authorizer, a Lambda function you own, for API Gateway to use to authorize the client requests for the configured APIs.

When an API request is made, API Gateway verifies whether a custom authorizer is configured for the API. If so, API Gateway calls the Lambda function, supplying the authorization token extracted from a custom request header. You use this Lambda function to implement various authorization strategies, such as JSON Web Token (JWT) verification and OAuth provider callout, to return IAM policies that authorize the request. If the returned policy is invalid or the permissions are denied, the API call will not succeed. For a valid policy, API Gateway caches the returned policy, associated with the incoming token and used for the current and subsequent requests, over a pre-configured time-to-live (TTL) period of up to 3600 seconds. You can set the TTL period to zero seconds to disable the policy caching. The default TTL value is 300 seconds. Currently, the maximum TTL value of 3600 seconds cannot be increased.

API Gateway custom authorization workflow

Create the API Gateway Custom Authorizer Lambda Function

Before creating an API Gateway custom authorizer, you must first create the AWS Lambda function that implements the logic to authenticate and authorize the caller. You can do so in the Lambda console, using the code template available from the API Gateway Custom Authorizer blueprint. Or you can create one from scratch. For illustration purposes, we will explain here the creation of the Lambda function without using the blueprint.

Note

The custom authorizer Lambda function presented here is for illustration purposes. In production code, you should follow the API Gateway Custom Authorizer blueprint to implement your authorizer Lambda function.

When creating the Lambda function for your API Gateway custom authorizer, you will be asked to assign an execution role for the Lambda function if it calls other AWS services. For the following example, the basic AWSLambdaRole will suffice. For more involved use cases, follow the instructions to grant permissions in an execution role for the Lambda function.

In the code editor of the Lambda console, enter the following Node.js code.


console.log('Loading function');

exports.handler = function(event, context) {
    var token = event.authorizationToken;
    // Call oauth provider, crack jwt token, etc.
    // In this example, the token is treated as the status for simplicity.

    switch (token) {
        case 'allow':
            context.succeed(generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            context.succeed(generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            context.fail("Unauthorized");
            break;
        default:
            context.fail("error");
    }
};

var generatePolicy = function(principalId, effect, resource) {
    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;
    }
    return authResponse;
}

        

The preceding Lambda function returns an Allow IAM policy on a specified method if the request's authorization token contains an 'allow' value, thereby permitting a caller to invoke the specified method. The function returns a Deny policy against the specified method if the authorization token has a 'deny' value, thus blocking the caller from calling the method. If the token is 'unauthorized', the client will receive a 401 Forbidden response. If the value that returns is 'fail' or anything else, the function returns a 500 Internal Server Error error message. In both of the last two cases, the calls will not succeed.

Note

In production code, you may need to authenticate the user before granting authorizations. If so, you can add authentication logic in the Lambda function as well. Consult the provider-specific documentation for instructions on how to call such an authentication provider.

Before going further, you may want to test the Lambda function from within the Lambda Console. To do this, configure the sample event to provide the input and verify the result by examining the output. The next two sections explain the Input to a Custom Authorizer and Output from a Custom Authorizer.

Input to an Amazon API Gateway Custom Authorizer

When a custom authorizer is enabled on an API method, you must specify a custom header for the method caller to pass the required authorization token in the initial client request. Upon receiving the request, API Gateway extracts the token from the custom header as the input authorizationToken parameter value into the Lambda function and calls the custom authorizer with the following request payload.


{
    "type":"TOKEN",
    "authorizationToken":"<caller-supplied-token>",
    "methodArn":"arn:aws:execute-api:<regionId>:<accountId>:<apiId>/<stage>/<method>/<resourcePath>"
}            
        

In this example, the type property specifies the payload type. Currently, the only valid value is the TOKEN literal. The <caller-supplied-token> originates from the custom authorization header in a client request. The methodArn is the ARN of the incoming method request and is populated by API Gateway in accordance with the custom authorizer configuration.

For the custom authorizer shown in the preceeding section, the <caller-supplied-token> string is allow, deny, unauthorized, or any other string value. An empty string value is the same as unauthorized. The following shows an example of such an input to obtain an Allow policy on the GET method of an API (ymy8tbxw7b) of the AWS account (123456789012) in any stage (*).


{
    "type":"TOKEN",
    "authorizationToken":"allow",
    "methodArn":"arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/"
}            
        

Output from an Amazon API Gateway Custom Authorizer

The custom authorizer's Lambda function must return a response that includes the principal identifier (principalId) and a policy document containing a list of policy statements. The following shows an example of a response.


{
  "principalId": "xxxxxxxx", // The principal user identification associated with the token send by the client.
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:<regionId>:<accountId>:<appId>/<stage>/<httpVerb>/[<resource>/<httpVerb>/[...]]"
      }
    ]
  }
}
        

Here, a policy statement stipulates whether to allow or deny (Effect) the API Gateway execution service to invoke (Action) the specified API method (Resource). You can use a wild card (*) to specify a resource type (method).

You can access the principalId value in a mapping template using the $context.authorizer.principalId variable. This is useful if you want to pass the value to the back end. For more information, see Accessing the $context Variable.

For information about valid policies for calling an API, see Statement Reference of IAM Policies for Executing API in API Gateway.

The following shows example output from the example custom authorizer. The example output contains a policy statement to block (Deny) calls to the GET method in an API (ymy8tbxw7b) of an AWS account (123456789012) in any stage (*).


{
  "principalId": "user",
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/"
      }
    ]
  }
}
        

Configure Custom Authorization Using the API Gateway Console

After you create the Lambda function and verify that it works, you can configure the API Gateway Custom Authorizer in the API Gateway console.

Create a Custom Authorization for API Methods

  1. Sign in to the API Gateway console.

  2. Create a new or select an existing API and choose Custom Authorizers.

  3. Under New Custom Authorizer, do the following:

    • In Name, choose a name for your new custom authorization.

    • In Lambda region, select the region where you upload your custom authorizer's Lambda function.

    • In Lambda function, select the Lambda function for your custom authorizer.

      Note

      You must first create a custom authorizer Lambda function in the region for it to be available in the drop-down list.

    • Leave Execution role blank to allow API Gateway to set a resource-based policy or type the name of your own IAM role to allow API Gateway to invoke the authorizer. For an example of such a role, see Set Up an IAM Role and Policy for an API to Invoke Lambda Functions.

    • In Identity token source, type the mapping expression for your authorizer's custom header.

      Note

      The custom header mapping expression is of the method.request.header.<name> format, where <name> is the name of a custom authorization header submitted as part of the client request. In the following example, this custom header name is Auth.

    • In Token validation expression, you can optionally provide a RegEx statement for API Gateway to validate the input token before calling the custom authorizer Lambda function. This helps you avoid or reduce the chances of being charged for processing invalid tokens.

    • In Result TTL in seconds, you can change or use the default (300) value to enable caching (>0) or disable caching (=0) of the policy returned from the Lambda function.

      Note

      The policy caching uses a cache key generated from the supplied token for the targeted API and custom authorizer in a specified stage. To enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce method-specific policy, you can set the TTL value to zero to disable policy caching for the API.

    Configure Method Request Custom Authorizer
  4. In Add Permission to Lambda Function, choose OK. After the custom authorization is created, you can test it with appropriate authorization token values to verify that it works as expected.

This completes the procedure to create a custom authorization. The next procedure shows how to configure an API method to use the custom authorizer.

Configure an API Method to Use the Custom Authorizer

  1. Go back to the API. Create a new method or choose an existing method. If necessary, create a new resource.

  2. In Method Execution, choose the Method Request link.

  3. In Authorization Settings, choose the pencil icon to edit the Authorization field. Select the custom authorization you just created (myTestApiAuthorizer), and then choose the checkmark icon to save the choice.

    Configure Method Request Custom Authorizer
  4. Optionally, while still on the Method Request page, choose Add header if you also want to pass the custom authorization header to the back end. In Name, type a custom header name that matches the header mapping expression you used when you created the custom authorization, and then choose the checkmark icon to save the settings.

  5. Choose Deploy API to deploy the API to a stage. Make a note of the Invoke URL value. You will need it when calling the API.

Call an API Using API Gateway Custom Authorization

After you configure your API to use the custom authorizer, you or your customers can call the API using the custom authorizer. Because it involves submitting a custom authorization token header in the requests, you need a REST client that supports this. In the following examples, API calls are made using the Postman Chrome App.

Calling an API with Custom Authorization Tokens

  1. Open the Postman Chrome App, choose the GET method and paste the API's Invoke URL into the adjacent URL field.

    Add the custom authorization token header and set the value to allow. Choose Send.

    Call API with Custom Authorization Allow Token

    The response shows that the API Gateway custom authorizer returns a 200 OK response and successfully authorizes the call to access the HTTP endpoint (http://httpbin.org/get) integrated with the method.

  2. Still in Postman, change the custom authorization token header value to deny. Choose Send.

    Call API with Custom Authorization Deny Token

    The response shows that the API Gateway custom authorizer returns a 403 Forbidden response without authorizing the call to access the HTTP endpoint.

  3. In Postman, change the custom authorization token header value to unauthorized and choose Send.

    Call API with Custom Authorization Unauthorized Token

    The response shows that API Gateway returns a 401 Unauthorized response without authorizing the call to access the HTTP endpoint.

  4. Now, change the custom authorization token header value to fail. Choose Send.

    Call API with Custom Authorization Fail Token

    The response shows that API Gateway returns a 500 Internal Server Error response without authorizing the call to access the HTTP endpoint.