Showing posts with label API Gateway. Show all posts
Showing posts with label API Gateway. Show all posts

AWS Custom / Lambda Authorizer

A Custom authorizer (also known as a Lambda authorizer) is an AWS API Gateway feature that uses a Lambda function to control access to your API. With Custom authorizer we can implement a custom authorization scheme that uses a bearer token authentication strategy such as OAuth or SAML, or that uses request parameters to determine the caller's identity.

When a client makes a request to one of our API's methods, API Gateway calls our Lambda authorizer, which takes the caller's identity as input and returns an IAM policy as output.


Types of Lambda Authorizer:

There are two types of Lambda autorizers
  1.  Token-based: Token-based authorizer receives the caller's identity in bearer token such as JWT token or oAuth token2
  2. Request-based: Request-parameter-based authorizer receives the caller's identity in combination of headers, query string params, stage variables and $context variables.


Lambda Authorization workflow for API gateway

  1. Client calls the API Gateway method with bearer token
  2. API gateway checks the method configured and Lambda authorizers. If yes, gateway calls the lambda function
  3. Lambda function authenticates the caller
  4. If the call succeeds, the Lambda function grants access by returning an output object containing at least an IAM policy and a principal identifier.
  5. API Gateway evaluates the policy.
    1. If access is denied, API Gateway returns a suitable HTTP status code, such as 403 ACCESS_DENIED.
    2. If access is allowed, API Gateway executes the method. If caching is enabled in the authorizer settings, API Gateway also caches the policy so that the Lambda authorizer function doesn't need to be invoked again. 


Steps to Create Lambda Authorizer

1) Create a lambda authorizer function


You need to first create the lambda function in AWS Console or in your local. In this tutorial I am used a .net core lambda function created in Visual studio. 
Note: You should have AWS Toolkit for visual studio to be installed to create AWS lambda in visual studio.
For creating a lambda function in Visual Studio
  1. Click on File -> New -> Project
  2. Choose "AWS Lambda" under "Visual C#" section and select "AWS Lambda Project(.Net core - C#)" template
  3. Select Empty Lambda template. It will create a skeleton as below
    namespace AWSLambda1
    {
     public class Function
     {
      public string FunctionHandler(string input, ILambdaContext context)
      {
       return input?.ToUpper();
      }
     }
    }
    
  4. Add Amazon.Lambda.APIGatewayEvents nuget package to the project
  5. Following is my code for a request based authorizer. It will read the accountid provider in the method url path and x-api-key from headers and validate those two. So modify the above function as below
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Amazon.Lambda.APIGatewayEvents;
    using Amazon.Lambda.Core;
    
    // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
    [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
    
    namespace AWSLambda1
    {
     public class Function
     {
      
      public async Task FunctionHandler(APIGatewayCustomAuthorizerRequest request, ILambdaContext context)
      {
       var authorized = false;
       int accountId = -1;
       string authToken = string.Empty;
       try
       {
        // Parse the accountId for the parameter values
        if (!string.IsNullOrEmpty(request.PathParameters["accountId"]))
         accountId = int.Parse(request.PathParameters["accountId"]);
    
        // Parse the api key from headers
        if (!string.IsNullOrEmpty(request.Headers["x-api-key"]))
         authToken = request.Headers["x-api-key"];
    
        if (accountId != -1 && !string.IsNullOrWhiteSpace(authToken))
        {
         authorized = (accountId == 1 && authToken == "xxxx-xxxx-xxxx-xxxx") ? true : false;
        }
       }
       catch (Exception ex)
       {
        context.Logger.Log(ex.Message);
       }
       return CreateResponse(request.MethodArn, authorized);
      }
    
      /// 
      /// Create policy and returns the Authorizer response
      /// 
      /// Method Arn
      /// If it is true, it will retun Allow policy otherwise return Deny policy
      /// 
      private static APIGatewayCustomAuthorizerResponse CreateResponse(string methodArn, bool authorized)
      {
       APIGatewayCustomAuthorizerPolicy policy = new APIGatewayCustomAuthorizerPolicy
       {
        Version = "2012-10-17",
        Statement = new List()
       };
    
       policy.Statement.Add(new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
       {
        Action = new HashSet(new string[] { "execute-api:Invoke" }),
        Effect = authorized ? "Allow" : "Deny",
        Resource = new HashSet(new string[] { methodArn })
    
       });
    
       APIGatewayCustomAuthorizerContextOutput contextOutput = new APIGatewayCustomAuthorizerContextOutput
       {
        ["User"] = "User",
        ["Path"] = methodArn
       };
    
       return new APIGatewayCustomAuthorizerResponse
       {
        PrincipalID = "User",
        Context = contextOutput,
        PolicyDocument = policy
       };
      }
     }
    }
    
  6. Create a package file with the following command in command prompt in the project folder
    dotnet-lambda package -c Release -o LambdaAuthorizer.zip -f netcoreapp2.1
    
  7. Login to AWS Console
  8. Create a .NET Core Lambda function by uploading the above package and save it.

2) Configure the Lambda function as an API Gateway authorizer

We need to configure the lambda function we created in step 1 in API gateway to use it as a authorizer. 
  1. In AWS Console, go to API gateway and choose your api from the list
  2. Goto Authorizers and Click "Create New Authorizer"
  3. Enter a name for the authorizer.
  4. Choose Type as Lambda.
  5. For Lambda Function, choose the region where you created your Lambda authorizer function and choose the function name from the dropdown list.
  6. Leave Lambda Invoke Role blank.
  7. For Lambda Event Payload, choose Request.
  8. Under Identity Sources, add a Header named "x-api-key"
  9. Choose Authorization Cache if required. 
  10. Click on "Create"
This will create new authorizer in your API Gateway. Now navigate to a api method for which you want to add authorization in the api gateway, Open "Method Request" -> Settings -> Select Your authorizer in Authorization dropdown

3) Test your API

Now test your api from Postman by passing the token in "x-api-keytest" header to the method

Happy Coding 😊!

Reference: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-lambda-function-create

AWS API Gateway: Use API Keys for authentication

API Gateway supports multiple mechanisms for controlling and managing access to your API. You can find those here. Usage Plans is one of the mechanism which allows you to provide API keys to your customers — and then track and limit usage of your API stages and methods for each API key

In this post, you will learn how to use API keys for authenticating the methods in the API gateway.

To set up API keys for API gateway we need to do the following steps

1) Create an API gateway with desired API methods

I am not going to explain this in this tutorial as it is out of the scope. You can learn how to create methods in API gateway from here 

2) Deploy the API to a stage

  • In the API Gateway main navigation pane, choose "Resources".
  • From the "Actions" drop-down menu, choose "Deploy API".
  • In the "Deploy API", select an existing "Deployment Stage" or create new Stage













  • Click on "Deploy"
  • It will deploy your api and give the api url

3) Create an API key(s) for the API

  • In the API Gateway main navigation pane, choose "API Keys".
  • From the "Actions" drop-down menu, choose "Create API key".





  • In "Create API key", 
    • Type an API key name in the Name input field.
    • Choose Auto Generate to have API Gateway generate the key value, or choose Custom to enter the key manually.
    • Enter description if you want 
    • Choose Save
    • Repeat this  step if you want to add more keys

  • It will create new key and will show as following. You can view the key by clicking on show button

4) Create a new usage plan

 Create a new usage plan. Add the deployed API stage to the usage plan. Attach an API key to the usage plan or choose an existing API key in the plan. Note the chosen API key value.

  • In the API Gateway main navigation pane, choose "Usage Plans".
  • Click on "Create" button
  • In "Create Usage Plan",
    • Type name of the usage plan
    • Enable Throttling, Quota if required (I disabled those in my case)
    • Click on Next 

    • In the next screen, click on "Add API Stage" 

    • Select your API -> Stage -> Click on checkmark
    •  Click on Next
    • In the next screen, "Create API Key and add to Usage Plan" if you want to add new api key or click on "Add API Key to Usage Plan" to add existing API key. Here I am selecting existing one

    •  Enter the name of the api key (created in Step 3) and click on checkmark. Repeat this if you want to attach another key to this Usage Plan
    • Click on "Done"

5) Configure API methods to require an API key

  • In the API Gateway main navigation pane, choose "Resources".
  • Under "Resources", choose an existing method.
  • Choose "Method Request".
  • Under the "Authorization Settings" section, choose true for "API Key Required".
  • Save the settings by clicking on checkmark icon.










6) Redeploy the API 

Redeploy the API to the same stage (Check Step 2 for deployment process)

The client can now call the API methods while supplying the x-api-key header with the chosen API key as the header value.

Happy Coding 😊!