Cognito user authentication on ALB vs API Gateway

Porsche Digital
#NextLevelGermanEngineering
7 min readNov 25, 2020

How to choose between cookie-based (Application Load Balancer) and token-based (API Gateway) authentication? In this article, Porsche Digital DevOps Engineer Aşkın Aşkın compares authentication on ALB and API Gateway.

Authentication is one of the most complicated topics for developers. It is needed to implement many features, from forgot password to SMS verification or Two-Factor-Authentification (2FA). However, with the latest technologies and services, a secure authentication system is simpler to implement than ever before. AWS Cognito is an authentication as a service just like Auth0 or others —but its main advantage is its integration with other AWS services.

Colorful lines of code written on a black computer screen
Authentication is one of the most complicated topics for developers. Photo by Markus Spiske on Unsplash

In this article, I will introduce two different services that AWS Cognito can integrate: Application Load Balancer (ALB) and API Gateway. For both methods, we first need to create a Cognito User Pool. As there are many resources for Cognito and User Pool creation, this article assumes a good familiarity with Cognito and focuses on integration with other services.

Both the methods and implementation will be discussed, showing step by step instructions and representations in Terraform.

ALB and API Gateway

An Application Load Balancer distributes the incoming request to targets and instances. The load balancer uses listeners to execute specific actions.

API Gateway is a management tool that stands between a client and backend services to intercept all incoming requests and send them with different functions. API Gateway is not enough to connect directly to containers — because of this, we used Network load balancer and Vpclink to connect to the container instance.

Authentication at Infrastructure

“Authentication at Infrastructure” is a term we can use for the setup which combines an identity provider like AWS Cognito and ALB or API Gateway. Because the authentication/authorization process is being handled at the infrastructure step with proven components, our software becomes simpler, easier to maintain and less error-prone.

Implementing authentication at infrastructure also gives the opportunity to implement authentication in IaC systems like CloudFormation or Terraform, which makes it a pluggable component. Whether if it’s implementing a new monolith with a completely different domain, or another microservice that we will attach to our fleet, the authentication service development can be mostly skipped in the application layer (with some exceptions) and implemented completely on IaC. This pluggable component also enables us to share user pools among different services/domains/monoliths.

Of course, using AWS Cognito as an authentication layer also has more advantages like but not limited to

  • Not having to re-invent the wheel: from sign-up forms to forgot password flows, batteries included
  • Very adaptive, customizable login/authentication system
  • AI-based fraud detection
  • SMS-based login
  • easy integration with other OAUTH providers, Google login, Facebook login, etc
  • and many more…

Implementing AWS Cognito at the infrastructure layer takes away lots of developers/hours spent on mundane and repeating tasks and makes it very easy to implement with a few lines of IaC.

Cognito implementation at ALB

Authentication flow follows a generic OAUTH flow, a token generated by AWS Cognito is via a redirect, and this token is exchanged for a Session Cookie as the last step. After this process is completed, on subsequent requests, ALB will verify the information in the cookie and transform it into the user’s information written into X-Amzn-Oidc-* headers. The application then can use said headers to operate on a logged-in user account.

ALB provides authentication through social Identity Providers (IdP) like Google, Facebook login to allow the user sign-in.

Cognito implementation at ALB

How to authenticate in ALB with Terraform

resource "aws_cognito_user_pool" "user_pool" {name = var.pool_name...}resource "aws_cognito_user_pool_client" "client" {name = var.client_nameuser_pool_id = aws_cognito_user_pool.user_pool.id}resource "aws_cognito_user_pool_domain" "domain" {domain       = var.domainuser_pool_id = aws_cognito_user_pool.user_pool.id}resource "aws_alb_listener" "listener" {...default_action{type = "authenticate-cognito"authenticate_cognito {user_pool_arn       = aws_cognito_user_pool.user_pool.arnuser_pool_client_id = aws_cognito_user_pool_client.client.iduser_pool_domain    = aws_cognito_user_pool_domain.domain.domain}}...}

How to authenticate in ALB with manual steps

  • Open EC2 page on AWS and Click Load Balancers.
  • Choose the load balancer you want to authenticate.
  • Click the Listeners tab and Click Add listener button.
  • Choose HTTPS under Protocol:port and be sure port is set to 443.
  • Click Add action and choose Forward to…
  • Choose the Target group you created and click the (tick) symbol.
  • Choose Default SSL certificate on the drop down list.
  • Click Save button.
  • Come back to Listeners and click View/edit rules.
  • Click + tab and + Insert Rule.
  • Click Add Condition and choose Path….
  • Enter the value and click the (tick) symbol.
  • Click Add action and choose Authenticate….
  • Choose Cognito user pool on the dropdown list or Create new.
  • Choose your client on the drop down list under App client.
  • Click the (tick) symbol.
  • Click Add action and choose Forward to…
  • Choose the Target group you created and click the (tick) symbol.
  • Click Save button.

Cognito implementation at API Gateway

API Gateway is another service that can work with AWS Cognito. While the purpose of API Gateway and ALB seems similar(routing requests to defined targets), API Gateway is a serverless service while ALB is not. According to my experience, Cognito integration with API Gateway is designed differently than ALB integration. Modern web applications can utilize API Gateways’s integration easily, especially with the combination of AWS Amplify SDK, the entire setup is really straightforward and powerful. It is also self-contained. There is no need to keep tokens on the backend. The token keeps all the data itself.

The setup is made by adding Cognito as an authorizer to a path. This makes incoming requests verified before getting sent to the application layer. AWS Gateway checks the incoming token, verifies it and if the token is valid, the requests are routed to targets.

Cognito implementation at API Gateway

How to authenticate in API Gateway with Terraform

variable "cognito_user_pool_name" {}data "aws_cognito_user_pools" "user_pools" {name = var.cognito_user_pool_name}resource "aws_api_gateway_rest_api" "rest_api" {name = var.api_name...}resource "aws_api_gateway_resource" "resource" {rest_api_id = aws_api_gateway_rest_api.rest_api.idparent_id   = aws_api_gateway_rest_api.rest_api.root_resource_idpath_part   = "{proxy+}"}resource "aws_api_gateway_authorizer" "authorizer" {name          = "Cognito-Authorizer"type          = "COGNITO_USER_POOLS"rest_api_id   = aws_api_gateway_rest_api.rest_api.idprovider_arns = data.aws_cognito_user_pools.user_pools.arns}resource "aws_api_gateway_method" "any" {rest_api_id   = aws_api_gateway_rest_api.rest_api.idresource_id   = aws_api_gateway_resource.resource.idhttp_method   = "ANY"authorization = "COGNITO_USER_POOLS"authorizer_id = aws_api_gateway_authorizer.authorizer.idrequest_parameters = {"method.request.path.proxy" = true}}

How to authenticate in API Gateway with manual steps

  • Open API Gateway console.
  • Choose your API to work on.
  • Choose Authorizers.
  • Chose Create New Authorizer.
  • Write a Name for the Authorizer.
  • Select type as Cognito.
  • Choose your Cognito User Pool under drop down list.
  • Enter Authorization for Token Source.
  • Leave Token validation blank and choose Create.
  • Choose Resources on the main list under API.
  • Choose the method you want to authenticate.
  • Click Method Execution.
  • Choose authorizer with as Authorization under Settings.

How to choose between API Gateway and ALB?

Instead of talking about the advantages and disadvantages of both integrations, let’s talk about when to use what.

  1. API Gateway is a serverless component, it has also many extra features compared to ALB. If starting a new project where a web application or mobile application needs authentication, then API Gateway is the better choice for most.
  2. If we have a dockerized application that’s just server-side rendered which we need to globally put behind an authentication mechanism, then ALB is the easy winner.

Summary

In this article, we compared authentication on ALB and API Gateway. Both tools have different roles in a complicated application landscape. Both implementations have similar features, but API Gateway gives us more flexibility in the implementation style. API Gateway is also incredibly powerful in serverless setup. For sustained heavy loads (IoT sensor data, streaming, etc), ALB has good uses. Being able to use both components in our projects with the same user pool is a really nice way of integrating domain-specific services.

For further reading about cookie-based (ALB) and token-based (API Gateway) authentication, I can recommend this guide: Cookies vs. Tokens: The Definitive Guide — DZone Integration

References:

https://aws.amazon.com/blogs/aws/built-in-authentication-in-alb/

https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-scenarios.html#scenario-api-gateway

Aşkın Aşkın

Aşkın Aşkın is DevOps Engineer at Porsche Digital in Berlin.

About this publication: Where innovation meets tradition. There’s more to Porsche than sports cars — we’re tackling new challenges, develop digital products, and think digital with a focus on the customer. On our Medium blog, we tell these stories. It’s about our #nextvisions, smart technologies, and the people that drive our digital journey. Please follow us on Twitter (Porsche Digital, Next Visions), Instagram (Porsche Digital, Next Visions, Porsche Newsroom), and LinkedIn (Porsche AG, Porsche Digital) for more.

--

--

Porsche Digital
#NextLevelGermanEngineering

Official Account of Porsche Digital | Follow us on LinkedIn for the latest news! | Our mission: To create value and spark excitement through digital engineering