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"
}
]
}
}
}
}
]
}