I tried to use Lambda @ Edge to apply Basic authentication to the site, but when I search in Japanese, I usually get a lot of articles such as Node 6 and 8. However, this limitation was just after the general release of Lambda @ Edge, and I felt that the information was too old, so I checked the current support status of Lambda @ Edge again. Then, at the moment (October 08, 2020), Lambda @ Edge can be used up to Python 3.8, so I decided to use this to apply Basic authentication, which is the purpose of this time.
The environment that can be executed at the time of writing the article (2020/10/08) is as follows.
Source: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda-function-configuration
It could be run in Python as well as Node.js. Looking at when this change came in, it seems that Python 3.7 was available in August 2019, and Python 3.8 and Node 12 were around March 2020.
By executing AWS Lambda between Amazon CloudFront requests, the necessary processing can be inserted separately from the application. See below for the officially introduced use cases.
https://aws.amazon.com/jp/lambda/edge/
This time, the purpose is to perform Basic authentication independently of the original content by inserting the Basic authentication process before the user (viewer) accesses CloudFront and accesses its cache and origin. ..
CloudFront is a global service that can be used in any region, but the resources used here (such as the certificate used by SSL Certificate Manager) must be created in the us-east-1 region. Create a Lambda function in this region as well.
The procedure for creating with the management console is shown below. As a prerequisite, it is assumed that you have the authority to create an appropriate Lambda or IAM Role, and that you have already completed the settings for CloudFront that uses Basic authentication.
--Open the Lambda page and press the "Create Function" button to start creating the function --Perform the initial settings according to the figure below. --When creating a new execution role -"Create a new role from an AWS policy template Grant "basic Lambda @ Edge permissions (for CloudFront triggers)" as " --If you already have a role with similar privileges, you can use it. --You can use any name you like
--Press Create Function to create a function --Rewrite the function code as follows --Here, the user name and password are determined by the ʻauthenticate` function, so rewrite it so that you can use it yourself. --In the Lambda Function used by Lambda @ Edge, ** environment variables cannot be used **, so it is written in solid form.
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Lambda for Basic authentication@The Python version of Edge.
"""
import base64
def authenticate(user, password):
"""Authentication"""
return user == 'cloudfront' and password == 'CL0UDFR0NT'
def lambda_handler(event, context):
request = event['Records'][0]['cf']['request']
headers = request['headers']
error_response = {
'status': '401',
'statusDescription': 'Unauthorized',
'body': 'Authentication Failed',
'headers': {
'www-authenticate': [
{
'key': 'WWW-Authenticate',
'value': 'Basic realm="Basic Authentication"'
}
]
}
}
if 'authorization' not in headers:
return error_response
try:
auth_values = headers['authorization'][0]['value'].split(" ")
auth = base64.b64decode(auth_values[1]).decode().split(":")
(user, password) = (auth[0], auth[1])
return request if authenticate(user, password) else error_response
except Exception:
#Format error etc.
return error_response
--Press the Deploy button to apply this code to $ LATEST
--Create a "new version" from the action
--Lambda @ Edge cannot use $ LATEST
, so be sure to issue a fixed version
--Make sure that the version is "the latest version currently created" and press the "+ Add trigger" button at the bottom left of the figure below.
--When you select CloudFront in the trigger settings, the item to set Lambda @ Edge for the already set CloudFront is displayed.
――You choose which distribution you want
-In "Select cache behavior", it will appear in the path unit specified in Behavior of CloudFront, so select the Behavior to which Lambda @ Edge is applied.
--When setting from the CloudFront side, set in Behavior in the same way.
--Set "Viewer Request" because you want to insert the process between " Viewer (User) "-> CloudFront
in CloudFront event.
--Agree to function replication to all regions
-Press "Add"
Once the above process is completed and applied to CloudFront, basic authentication will be required for access.
What I actually did.
--Lambda @ Edge doesn't return the expected results
--Because the version was not fixed. The version needs to be fixed properly
--Lambda @ Edge's Lambda function doesn't show the log when I try to "View CloudWatch Log"
--Recorded in CloudWatch logs for the region actually processed
--This time, a log group called /aws/lambda/us-east-1.cloudfront-basic-auth
was created in the ap-northeast-1 region and the log was output here.
--Basic authentication does not pass no matter how many times you enter
--The default setting for CloudFront events is "Origin Request", so you need to change this to "Viewer Request" correctly.
--In the default Origin Request Policy, the ʻAuthorization header is set not to flow to the origin. If you put Lambda @ Edge here, the authentication token will not be passed to Lambda @ Edge in the first place, so ʻerror_response
will always be returned.
In the early article, I had the impression that the initial setting was difficult due to various IAM Role settings, but at the moment I found that Lambda @ Edge can be easily realized by using the wizard without thinking difficult. It may not be used when protecting the development site from general access, applying Basic authentication to the site as a completely internal service, or adding Basic authentication to the root path of the site management screen etc. Is it?
Recommended Posts