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
- Create a sample Lambda REST API
- Create a trigger on API Gateway
- 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'
Step 2 - Author from scratch and API, Give it any name and create a new role for Lambda execution
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;
};
Step 4 - Once the Lambda is created we will create an API Gateway trigger which will basically call this Lambda on the endpoint invocation
b. Select the source as API Gateway
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
Step 5 - On the API, click on Configuration tab and click on Triggers, Note the API Endpoint and click on it to open it.
Step 6 - You will be able to view the result from the endpoint.
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
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);
}
Step 9 - Add the code and now click 'Deploy'
Step 10 - Now, go to API Gateway and click on the API Name. NOTE:- you need to go to API Gateway not AWS Lambda.
Step 11 - Now go to Authorizers _and click on _Create authorizer
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
Step 13 - Now go back to the authorizer that is created and click on its details
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
b. if you give any values that are not acceptable then it will return a 401
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)