documents/dev/snippets/aws/S3-Cloudfront password-protect.md

AWS s3 cloudfront password-protect

The cloudfront behavior requires that the lambda function associations need to be in us-east-1 (North Virginia) for some reason.

  • Select the N. Virginia region from top right menu.
  • Go to the lambda service from console
  • Create Function -> Browse Serverless App Repository
  • Search for cloudfront-response-generation and deploy
  • Enter the javascript code below into index.js, publish version, copy ARN (with the version number at the end)
  • Go to cloudfront -> select distribution -> click Distribution Settings
  • Click Behaviors tab -> select the s3 origin -> click edit
  • Scroll down to Lambda Function Associations, select Viewer Request
  • Paste the Lambda Function ARN
exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  if(request.uri.match('/lib/')) {
    callback(null, request);
  } else {
    checkCredentials(event, context, callback);
  }
}

function checkCredentials(event, context, callback) {

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

  // Specify the username and password to be used
  const user = 'gerenuk';
  const pw = 'Jadzia@@0720';

  // Build a Basic Authentication string
  const authString = 'Basic ' + new Buffer(user + ':' + pw).toString('base64');

  // Challenge for auth if auth credentials are absent or incorrect
  if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
    const response = {
      status: '401',
      statusDescription: 'Unauthorized',
      body: 'Unauthorized',
      headers: {
        'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
      },
    };
    callback(null, response);
  }

  // User has authenticated
  callback(null, request);

};
// sample event
{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionId": "EXAMPLE"
        },
        "request": {
          "uri": "/test",
          "method": "GET",
          "clientIp": "2001:cdba::3257:9652",
          "headers": {
            "host": [
              {
                "key": "Host",
                "value": "d123.cf.net"
              }
            ]
          }
        }
      }
    }
  ]
}