I would like to set up an Amazon S3 account, create a bucket, upload some data, and that this data will be available using HTTP GET with basic authentication
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:s3auth@maven.s3auth.com/texry/packages.png
Check also this article: Basic HTTP Auth for S3 Buckets
I myself was trying to find solution to this problem. This post here has listed them all. Quoting the lines:
I’ve been looking for months for a solution to add Basic HTTP Authentication to S3 buckets on Amazon. There are options involving pre-signed URLs (single object only), using a 3rd-party free or commercial service (privacy concerns), spinning up an EC2/Heroku/etc. with middleware to proxy requests (complicated and not serverless), using page redirects and bucket policies (not secure).
Bucket policies solution: I have personally tried this and it seems perfectly secure to me (unless you have a way to bypass aws bucket policies). It just requires s3 bucket to operate. Simple to implement. Basic idea:
Using aws Lambda@Edge: This solution require s3, aws lambda and aws cloudfront to operate. Basic idea:
No this is not possible. You have to conform to Amazons Authentication API
Check out some of the of wrappers listed here.
I'm from AdroitLogic. About the linked article, it shows how the UltraESB could be placed between your client and Amazon S3 to authenticate your requests. If required, it could create a "proxy" service which will accept basic authentication from your client, and send the credentials the way Amazon S3 expects. This could be done in a trivial manner, and will hide any complexity for your client.
This is now possible using CloudFront and Lambda@Edge (generally available since July 2017 in the us-east-1 region).
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.