Authenticate Lambda Requests with ALB and Google OAuth: Part 1
Build an Application Load Balancer that uses OAuth2.0 to authenticate requests to Lambda services.
Recently, a serverless pattern was introduced that leverages Application Load Balancers (ALB) in front of Lambda functions instead of API Gateway (API GW).
In a two-part series, I will explain how to configure an HTTPS ALB that authenticates through an OpenID Connect (OIDC) compliant identity provider (IdP) using CloudFormation. For this tutorial, we will use Google as our identity provider, but keep in mind that any OIDC-compliant IdP will work.
This article will present the steps to take before building an Application Load Balancer that will authenticate requests via OpenID Connect.
In a followup article, I will provide a sample serverless project that uses an HTTPS ALB to authenticate requests to the different Lambda services.
Before we can build our application, we’ll need to satisfy some high-level requirements.
What we’ll need
Before creating an HTTPS ALB, there are some application components that we will need to create. In order to make requests to the ALB, we’ll need to perform the following steps:
- Register a Route53 Domain.
- Create an SSL Certificate for our domain using the AWS Certificate Manager Service.
- Create a Google OAuth Client.
After authenticating through Google’s OAuth client, our ALB will forward the requests to the appropriate Lambda services, which will return a response specifically formatted for the ALB’s consumption. Assuming that the response is formatted correctly, the ALB will return the response back to the user.
Before we get to the how, let’s discuss the why — as in, why should I go through the trouble of setting up an HTTPS ALB rather than using API GW?
Let’s Talk About Cost
While API Gateway has a robust set of features for Authentication and Authorization and is really easy to configure for a serverless application, it does not always scale well from a cost perspective. For a deep dive on the cost analysis between API GW and ALB, this article written by Jeremy Thomerson does a wonderful job at comparing the two services.
Jeremy’s main point is that the budget for an application should be driven by compute and storage (Lambda and DynamoDB in this case) and NOT the service making requests. For example, his API Gateway averages around 450 requests per second, which costs 4x the price of his compute and storage services combined. He estimates that by switching to an ALB he can save up to 65% per month.
Application Load Balancer will cost you — at minimum — around $15 per month because it’s billed hourly. If you run your API in multiple regions, multiply that $15 (or up to around $20 for some regions) by the number of regions you have. $15 worth of API Gateway calls will net you around 4.3 million API calls per month (well, 5.3 million if you count the free tier). 5.3 million API calls is only around two requests per second. So, if your API is used very much at all you could easily end up paying more for API Gateway than you would for Application Load Balancer.
While the cost savings potential is exciting, the lack of documentation for creating an HTTPS ALB with CloudFormation makes building the application difficult. To complicate things further, if you want to authenticate directly through an OIDC-complient IdP rather than Cognito, it becomes even more challenging.
In order to save you time and energy researching the topic, I have put together a step-by-step guide to prepare your application for ALB authentication.
Register a Route53 Domain
In order to serve requests from an HTTPS ALB, we’ll need a Route53 Registered Domain. When we eventually define our ALB, we will need a valid SSL/TLS certificate from the AWS Certificate Manager. However, the certificate provided by the certificate manager must be issued to a valid domain name.
In the AWS Console, navigate to the Route53 service dashboard. On the left menu, select Registered Domains and click Register Domain. You should now be looking at the below screen. Choose your domain name and click Continue.
On the next screen there will be a list of available domain names related to the one you entered. If the domain you want is available, it will appear at the top of the list. Click Add to cart for the domain name you would like to use and then select Continue.
After that, fill out your contact information, leaving the options for My Registrant, Administrative and Technical Contacts are all the same and Privacy Protection set to “Yes” and “Enabled”, respectively.
On the last page, leave all defaults alone and check that you have read and agreed to the terms and conditions.
Open up the email that you provided in your contact information and you will see a message asking you to verify that you are registering this Route53 Domain. Once you have verified, go back to the Route53 console and click Complete Order.
Amazon says that the domain registration can take up to 24 hours, but in my experience it takes anywhere from half an hour to an hour. Once our domain has been registered, move on to the next step.
Create a Certificate for your Domain
The next thing we’ll have to do in order to deploy an HTTPS ALB is create an SSL/TLS certificate for our registered domain using AWS’s Certificate Manager (ACM).
From the AWS Console, navigate to the Certificate Manager dashboard and click Request a certificate. Leave the default option to request a public certificate and then click the Request a certificate button at the bottom of the page.
On the following page, enter your domain name an click Next.
Next, select Email Validation and click Next. This step is extremely important, as you will need to validate your certificate through the contact email you provided for your registered Domain.
Enter any tags you would like to use and click Review. On the Review page, make sure that the validation method is set to “Email” and then click Confirm and Request.
Go to your email inbox and verify your certificate. We will need the Amazon Resource Name (ARN) of the certificate when we create the application load balancer in the next article.
The last thing we’ll need to do before we can create out ALB is set up our OIDC-compliant IdP. In this example, we will use Google’s OAuth Client.
Create a Google OAuth Client
The last thing we’ll need to do before building our Application Load Balancer is to create our Google OAuth client. Once the client is built, we can tell our ALB to authenticate requests through the OAuth client.
- Open the Google API Console Credentials page.
- In the search bar, enter Create a Project and select Create a Project.
- Enter a Project Name and click Create.
4. Make sure your project is selected from the drop down box and then select the Oauth consent screen tab. Select the “External” radio button and click Create.
5. In the App information section, add an application name and a user support email.
6. In the Authorized domains section, select ADD DOMAIN and add your Route53 domain.
7. Add your email address in the “Developer contact information” and then click SAVE AND CONTINUE.
8. On the following page click on ADD OR REMOVE SCOPES and choose the following scopes:
- email: Shares the user’s email address in the request header.
- profile: Shares the user’s Google profile information (first name, last name, profile picture, etc.) in the request header.
- openid: Allows our ALB to authenticate with Google’s OAuth client.
9. Click Update and then click SAVE AND CONTINUE at the bottom of the page.
10. Add yourself as a test user and then click SAVE AND CONTINUE one more time.
11. Next, Select the “Credentials” tab and click Create Credentials -> OAuth client ID.
12. For the purposes of this tutorial, set your “Application Type” to “Web application”.
13. Enter a name for your Web client.
14. Select Add URI in the section, “Authorized redirect URIs”. Add a redirect URI in the following form:
15. Click CREATE and save the “Client ID” and “Client Secret” in a safe place.
Alright, that’s it for this article! In the next part of this series, I’ll walk you through the Application Load Balancer and Lambda configuration that will allow you to authenticate requests to your Lambda services with an HTTPS ALB built entirely through CloudFormation.