DEV Community

Using Custom Authorization - Request based for AWS Lambda

Many a time we face a challenge for our Lambda function endpoints where a customer autorization is required.
Below is a post which shows how to implement a Request based Custom Authorization for AWS Lambda.

A Lambda authorizer, formerly known as custom authorizer, controls API access using a Lambda function. It's beneficial for custom authorization with bearer token authentication like OAuth or SAML OR request parameter based authentications. It processes the caller's identity and returns an IAM policy. There are two types: TOKEN authorizer for bearer tokens and REQUEST authorizer for parameters. WebSocket APIs only support REQUEST authorizers. You can use Lambda functions across AWS accounts for authorizers.

In this part, I will show you how to create a request based token.

It will cover 3 high level steps

  1. Create a sample Lambda REST API
  2. Create a trigger on API Gateway
  3. Create the customer Authorizer and attach it to API and test it.

*Step 1 *- Go to AWS Console, select Lambda and click on 'Create Function'

Image description

Step 2 - Author from scratch and API, Give it any name and create a new role for Lambda execution

Image description

Step 3 - Customize the output message with your favourite Hello world message. My sample as below

export const handler = async (event) => {
  // TODO implement
  const response = {
    statusCode: 200,
    body: JSON.stringify('You have called My Rest API!'),
  };
  return response;
};
Enter fullscreen mode Exit fullscreen mode

Step 4 - Once the Lambda is created we will create an API Gateway trigger which will basically call this Lambda on the endpoint invocation

a. Click on add trigger
Image description

b. Select the source as API Gateway
Image description

c. Fill in the required Trigger parameters to expose it as a REST API and click on Create. Note the security parameter is kept as OPEN. This is specifically to test our scenarios
Image description

Step 5 - On the API, click on Configuration tab and click on Triggers, Note the API Endpoint and click on it to open it.

Image description

Step 6 - You will be able to view the result from the endpoint.

Image description

Step 7 - Now we will create the authorizer function, Go back to Lambda function, and click on 'Create Function'. Fill in the details as below

Image description

Step 8 - Now under the code section, fill in the below code.
This is a sample code from AWS blogs. Importantly look for the Header, QueryParam and StageVariable validation conditions.
This will be the one which will be request-based authorizer.

   // 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 === "H1"
        || queryStringParameters.QueryString1 === "Q1"
        || stageVariables.StageVar1 === "S1") {
        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);
}
Enter fullscreen mode Exit fullscreen mode

Step 9 - Add the code and now click 'Deploy'

Image description

Step 10 - Now, go to API Gateway and click on the API Name. NOTE:- you need to go to API Gateway not AWS Lambda.

Image description

Step 11 - Now go to Authorizers _and click on _Create authorizer

Image description

Step 12 - Next up, we need to create the autorizer with the right Identify source type and the key values.
One which we are doing here are Header, Query String and StageVariable. There are few others also based on which you can perform the authorization

Image description

Step 13 - Now go back to the authorizer that is created and click on its details

Image description

Step 14 - Next screen will give you the option to test the authorization,

a. if you give any values that are acceptable then it will return a 200

Image description

b. if you give any values that are not acceptable then it will return a 401

Image description

So in this way you can achieve custom authorization for your code very quickly.

Hope this was useful to you. And in the next blog I will show creation of a token based authorizer.

Top comments (0)