Previously, I’ve published a blog post about deploying static content on heroku with basic authentication. The main purpose was to get basic auth for a freely hosted static website. In that post, we hosted the source code on GitLab and configured a CI/CD pipeline to render the static content a.k.a html files and push the rendered files to Heroku. So the generated content is hosted on Heroku with basic authentication.
In this post, we’ll do something similar using AWS. It’s very easy and took me couple of minutes to figure it out. I’ll not go into detail but only share the steps and related links. So, it won’t be a long post. Let’s start.
Create an S3 bucket. Enable static website hosting and block all public access in the bucket configuration. We’ll allow access only through Cloudfront.
Go to CloudFront, distributions and create a new one. Add the S3 bucket you’ve just created as an origin. While configuring the origin select “use OAI” in S3 bucket access section. Optionally, you can define a custom domain name too.
Now, you should be able to access to the content hosted in S3 bucket via the domain name of the cloudfront distribution. You can upload a simple index.html manually to the S3 bucket to test it.
To have basic authentication we’ll use CloudFront Functions. Create a new function, copy paste the code below which is originally copied from here.
var USERNAME = 'USERNAME';
var PASSWORD = 'PASSWORD';
var response401 = {
statusCode: 401,
statusDescription: 'Unauthorized',
headers: {
'www-authenticate': {value:'Basic'},
},
};
function validateBasicAuth(authHeader) {
var match = authHeader.match(/^Basic (.+)$/);
if (!match) return false;
var credentials = String.bytesFrom(match[1], 'base64').split(':');
return credentials[0] === USERNAME && credentials[1] === PASSWORD;
}
function handler(event) {
var request = event.request;
var headers = request.headers;
var auth = (headers.authorization && headers.authorization.value) || '';
if (!validateBasicAuth(auth)) return response401;
return request;
}
Return back to CloudFront distribution you’ve configured. Go to behaviours, you’ll see a single behaviour with path pattern ‘Default (*)’. Edit it, go to Function associations and select the basic authentication function for Viewer request.
Optionally, you can configure different behaviours for different Path patterns instead of adding basic auth for whole site (*), you can add it for specific paths
specific_path/*
.You are done on the AWS side. Now you’ll need a job that will push your static content to the S3 bucket. This part can be configured via Gitlab CI/CD, Github Actions or whatever you use.
This time I’ve used GitHub Actions instead of GitLab CI/CD. And it went very easy, thanks to s3-sync-action.
- To be able to push content to S3 we’ll need
access_key_id
andsecret_access_key
and the user related to these keys should’ve permissions to read/write on the S3 bucket we use. Go to IAM service in AWS console, create a new user if you don’t have a suitable one. Make sure the user have permissions for S3 service. Go to security credentials tab of the user and create a access key. Copy the credentials somewhere safe. You’ll use them to push content to the S3 bucket.
Good job, have fun!