Basic User Authentication for Static Site using AWS & S3 Bucket

Gideon B picture Gideon B · Apr 26, 2019 · Viewed 7.5k times · Source

I am looking to add Basic User Authentication to a Static Site I will have up on AWS so that only those with the proper username + password which I will supply to those users have access to see the site. I found s3auth and it seems to be exactly what I am looking for, however, I am wondering if I will need to somehow set the authorization for pages besides the index.html. For example, I have 3 pages- index, about and contact.html, without authentication setup for about.html what is stopping an individual for directly accessing the site via www.mywebsite.com/about.html? I am more so looking for clarification or any resources anyone can provide to explain this!

Thank you for your help!

Answer

hephalump picture hephalump · Apr 27, 2019

This is the perfect use for Lambda@Edge.

Since you're hosing your static site on S3, you can easily and very economically (pennies) add some really great features to your site by using CloudFront, AWS's content distribution network, to serve your site to your site. You can learn how to setup host your site on S3 with CloudFront (including 100% free SSL) here.

While your CloudFront distribution is deploying, you'll have some time to go setup you Lambda, that you'll be using to do the basic user auth. If this is your first time creating a Lambda or creating a Lambda for use @Edge the process is going to feel really complex, but if you follow my step-by-step instructions below you'll be doing serverless basic-auth that is infinitely scaleable in less than 10 minutes. I'm going to use us-east-1 for this and it's important to know that if you're using Lambda@Edge you should author your functions in us-east-1, and when they're associated with your CloudFront distribution they'll automagically be replicated globally. Let's begin...

  1. Head over to Lambda in the AWS console, and click on "Create Function"
  2. Create your Lambda from scratch and give it a name
  3. Set your runtime as Node.js 8.10
  4. Give your Lambda some permissions by selecting "Choose or create an execution role"
  5. Give the role a name
  6. From Policy Templates select "Basic Lambda@Edge permissions (for CloudFront trigger)"
  7. Click "Create function"
  8. Once your Lambda is created take the following code and paste it in to the index.js file of the Function Code section - you can update the username and password you want to use by changing the authUser and authPass variables:
'use strict';
exports.handler = (event, context, callback) => {

    // Get request and request headers
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    // Configure authentication
    const authUser = 'user';
    const authPass = 'pass';

    // Construct the Basic Auth string
    const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');

    // Require Basic authentication
    if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
        const body = 'Unauthorized';
        const response = {
            status: '401',
            statusDescription: 'Unauthorized',
            body: body,
            headers: {
                'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
            },
        };
        callback(null, response);
    }

    // Continue request processing if authentication passed
    callback(null, request);
};

  1. Click "Save" in the upper right hand corner.
  2. Now that your Lambda is saved it's ready to attach to your CloudFront distribution. In the upper menu, select Actions -> Deploy to Lambda@Edge.
  3. In the modal that appears select the CloudFront distribution you created earlier from the drop down menu, leave the Cache Behavior as *, and for the CloudFront Event change it to "Viewer Request", and finally select/tick "Include Body". Select/tick the Confirm deploy to Lambda@Edge and click "Deploy".

And now you wait. It takes a few minutes (15-20) to replicate your Lambda@Edge across all regions and edge locations. Go to CloudFront to monitor the deployment of your function. When your CloudFront Distribution Status says "Deployed" your Lambda@Edge function is ready to use.