Does Amazon S3 support HTTP request with basic authentication
This is now possible using CloudFront and Lambda@Edge (generally available since July 2017 in the us-east-1 region).
- Create a S3 bucket
- Setup a CloudFront distribution in-front of the bucket, restricting access to the bucket so that only CloudFront can access it directly
- Create a Lambda function, which will mimic Basic HTTP Auth handshake with the browser. Assign it to the CloudFront
Viewer Request
behavior.
Here's the Lambda function: https://gist.github.com/lmakarov/e5984ec16a76548ff2b278c06027f1a4
Here's an article with more details: https://medium.com/@lmakarov/serverless-password-protecting-a-static-website-in-an-aws-s3-bucket-bfaaa01b8666
The short answer is no, not using basic auth. But here is a way that is effectively the same as basic auth, and that is easily than other solutions listed. I believe it is secure, but I don't know for sure.
You can set conditions on s3 buckets that match the headers on the request. As an example you can use the useragent
, and referer
headers as something equivalent to username and password in basic auth. Normally the useragent is the browser, and OS (like Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0)
, and the referer is the previous webpage.
Here is an example s3 bucket policy that allows putting objects, and getting objects by matching the useragent, and referer (note change: BUCKETNAME
, USERNAME
, PASSWORD
, AWS_REGION
, and FILENAME
to your details):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "allow-username-and-password-access",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::BUCKETNAME/*",
"Condition": {
"StringEquals": {
"aws:UserAgent": "USERNAME",
"aws:Referer": "PASSWORD"
}
}
}
]
}
To put a resource in the bucket you can use a curl request like this (note change: BUCKETNAME
, USERNAME
, PASSWORD
, AWS_REGION
, and FILENAME
):
curl --user-agent USERNAME --referer PASSWORD --upload-file "FILENAME" --request PUT "https://s3-AWS_REGION.amazonaws.com/BUCKETNAME/FILENAME"
To get use the resource you can use something like this:
curl --user-agent USERNAME --referer PASSWORD "https://s3-AWS_REGION.amazonaws.com/BUCKETNAME/FILENAME" > FILENAME
Once again, I believe this is secure, as the useragent, and referer should be encrypted if you are using https, but please tell me if it is not.
You can develop it yourself as a web app or a part of your existing application. It will consume HTTP requests, retrieve their URI component, convert it to S3 object name and use getObject() to get its content (using one of available S3 SDKs, for example AWS Java SDK).
Otherwise, you can try a hosted solution - s3auth.com (I'm a developer). It's an open source project, and you can see how this mechanism is implemented internally at one of its core classes. HTTP request is processed by the service and then re-translated to Amazon S3 internal authentication scheme:
This architecture diagram explains how the project is implemented. The PNG picture is loaded from Amazon S3 bucket maven.s3auth.com
, which is not readable anonymously. Full URL of this image is
http://s3auth:[email protected]/texry/packages.png
Check also this article: Basic HTTP Auth for S3 Buckets
By layering multiple AWS services you can achieve something close to Basic HTTP Authorisation.
- Create a s3 static site.
- Create a CloudFront Distribution to serve the s3 static site (use the static site url and not the bucket name)
- Use AWS WAF to create a rule which only allows requests with the correct http Authorization header. This will be a sting match rule on the contents of the Authorization header.
- Use Route53 to route a custom domain to the CloudFront Distribution
You should now have a static site which can only be accessed with the correct username and password.
NOTE: using this setup you will not be prompted for you credentials as the request is blocked with a 403 Forbidden instead of 401 Unauthorized.
NOTE: You can create a CloudFront distribution in front of a s3 bucket directly, but you will not be able to default to a root index file in sub-folders.