AmazonS3是否支持基本身份验证的 HTTP 请求

我想建立一个 Amazon S3帐户,创建一个桶,上传一些数据,这些数据将使用 HTTP GET 基本认证提供。

我知道有几种方法可以对 S3数据进行身份验证(查询字符串等) ,但是我希望能够提供一个简单的用户名/密码身份验证方案。

这可能吗?

78971 次浏览

不,这不可能。 你必须遵守亚马逊验证 API

检查一些包装器列出的 给你

我是 AdroitLogic 的。关于链接的文章,它展示了如何将 UltraESB 放置在客户机和 AmazonS3之间,以验证请求。如果需要,它可以创建一个“代理”服务,该服务将接受来自客户端的基本身份验证,并按照 Amazon S3期望的方式发送凭据。这可以通过一种简单的方式来完成,并且可以为您的客户机隐藏任何复杂性。

您可以自己开发它作为一个 Web 应用程序或现有应用程序的一部分。它将使用 HTTP 请求,检索它们的 URI 组件,将其转换为 S3对象名,并使用 GetObject ()获取其内容(使用可用的 S3 SDK 之一,例如 AWS Java SDK)。

否则,您可以尝试托管解决方案 -S3auth.com(我是一名开发人员)。这是一个开源项目,您可以在 它的核心类之一中看到这种机制是如何在内部实现的。HTTP 请求由服务处理,然后重新转换为 AmazonS3内部身份验证方案:

这个体系结构图解释了项目是如何实现的。PNG 图片是从 Amazon S3 bucket maven.s3auth.com加载的,这是不可匿名读取的。此图像的完整 URL 为

http://s3auth:s3auth@maven.s3auth.com/texry/packages.png

也可以查看这篇文章: S3存储桶的基本 HTTP 授权

通过将多个 AWS 服务分层,您可以实现类似于基本 HTTP 授权的功能。

  1. 创建 s3静态站点。
  2. 创建 CloudFront 发行版来为 s3静态站点提供服务(使用静态站点 URL 而不是 bucket 名称)
  3. 使用 AWS WAF 创建一个规则,该规则只允许具有正确的 http Authorization 头的请求。这将是 Authorization 标头内容上的一个骗局匹配规则。
  4. 使用 Route53将自定义域路由到 CloudFront 分发

您现在应该有一个只能用正确的用户名和密码访问的静态站点。

注意: 使用此设置时,不会提示您输入凭据,因为请求被 403号禁区而不是 未经授权阻塞。

注意: 您可以直接在 s3 bucket 前面创建 CloudFront 发行版,但是您不能在子文件夹中默认创建根索引文件。

现在可以使用 CloudFront 和 Lambda@Edge (通常自2017年7月起在 us-east-1区域提供)实现这一点。

  1. 创建一个 S3存储桶
  2. 在 bucket 前面设置 CloudFront 发行版,限制对 bucket 的访问,以便只有 CloudFront 可以直接访问它
  3. 创建一个 Lambda 函数,它将用浏览器模仿基本 HTTP Auth 握手。将其分配给 CloudFront Viewer Request行为。

下面是 Lambda 函数: Https://gist.github.com/lmakarov/e5984ec16a76548ff2b278c06027f1a4

下面是一篇更详细的文章: Https://medium.com/@lmakarov/serverless-password-protecting-a-static-website-in-an-aws-s3-bucket-bfaaa01b8666

简短的回答是否定的,不使用基本认证。但是这里有一种方法实际上与基本认证相同,并且比列出的其他解决方案更容易。我相信它是安全的,但我不确定。

您可以在 s3存储桶上设置与请求头匹配的条件。作为一个示例,您可以使用 useragentreferer头作为与基本认证中的用户名和密码等价的内容。通常用户代理是浏览器,而操作系统(如 Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0),和引用是前一个网页。

下面是一个示例 s3 bucket 策略,它允许放置对象,并通过匹配用户代理和引用来获取对象(注意更改: BUCKETNAMEUSERNAMEPASSWORDAWS_REGIONFILENAME) :

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

要将一个资源放到 bucket 中,可以使用像下面这样的 curl 请求(注意: BUCKETNAMEUSERNAMEPASSWORDAWS_REGIONFILENAME) :

curl --user-agent USERNAME --referer PASSWORD --upload-file "FILENAME" --request PUT "https://s3-AWS_REGION.amazonaws.com/BUCKETNAME/FILENAME"

要使用这个资源,你可以使用下面这些东西:

curl --user-agent USERNAME --referer PASSWORD "https://s3-AWS_REGION.amazonaws.com/BUCKETNAME/FILENAME" > FILENAME

再一次,我相信这是安全的,作为用户代理,和引用应该加密,如果你使用 https,但请告诉我,如果它不是。

我自己也在努力寻找这个问题的解决方案。这里的 这个帖子列出了所有的问题:

几个月来,我一直在寻找一种解决方案,将基本 HTTP 身份验证添加到 Amazon 上的 S3存储桶中。还有一些选项涉及预先签名的 URL (只针对单个对象)、使用第三方免费或商业服务(隐私问题)、利用中间件将一个 EC2/Heroku/等转换为代理请求(复杂而非无服务器)、使用 页重定向和桶策略(不安全)。

水桶政策解决方案: 我个人已经尝试过这个,它似乎对我来说是完全安全的(除非你有办法绕过法律桶政策)。它只需要 s3桶操作。很容易实现。基本理念:

  1. 限制访问整个网站,除了允许公众访问条目文件和机密文件。
  2. 条目文件 安全,它接受用户输入的密码并重定向到 Secret File
  3. 重定向到主文件(index.html)的 Secret File 这是个秘密,该主文件承载站点的真实内容
  4. 主文件 主要内容,只允许访问来自同一站点的请求。
  5. 所有其他内容,比如 css、 js 文件都会受到 bucket 策略的限制,该策略允许它们在请求来自 bucket URL 的情况下提供服务。

使用 aws Lambda@Edge: 这个解决方案需要 s3、 aws Lambda 和 aws Cloudfront 来操作:

  1. 创建一个 安全。在此创建文本框以输入用户的基本凭据。这个文件应该是可公开访问的,并且应该调用一个 lambda 函数。
  2. 在配置 Cloudfront 时,会创建一个行为,即“如果您想访问 index.html,则需要通过 Signed URL 进行访问”。
  3. 和上面一样,创建一个 bucket 策略,只有当原点是 bucket URL 时才允许访问 js、 css 等文件。

看看 我的答案就在这里在这个有点相关的问题。

这里的问题是获得一个 bucket-object LIST,而不需要大量的 S3登录身份验证。所以从你的问题来看,我的答案并没有真正解释你对 Http-request with basic username/password authentication的询问——而是提供了一种可能性,即使知道 identity-pool (ID)Amazon Resource Name (ARN)(你可以认为它们类似于用户名和密码) ,也可以将 bucket 设置为私有,并且仍然检索它的数据。当然,要获得(ID)和(ARN) ,您必须做一些设置——在 AWS 主页 正如我在这里的17步回答中所描述的..。中工作——而且,它不是 GET 请求的一部分,而是在 Amazon 提供的 AWSS3框架中给出的。我希望,它仍然给你的问题提供了更多的选择;)

到目前为止,这在 AWS 上已经变得相对简单了。基本上有三件事需要做:

  1. 创建 CloudFront 函数将 BasicAuth 添加到请求中。
  2. 在一些地方正确配置 CloudFront 分布的起源。
  3. 激活 CloudFront 函数。

就是这样,没有特别的铃铛和口哨,否则。这是我所做的:

首先,转到 CloudFront,然后点击左边的函数,创建一个新的函数,命名为自己选择的名称(不需要区域等) ,然后添加以下代码作为函数的代码:

function handler(event) {
var user = "myuser";
var pass = "mypassword";
var requiredAuth = "Basic " + `${user}:${pass}`.toString('base64');


var authHeader = event.request.headers.authorization;


if (authHeader && authHeader.value === requiredAuth) {
return event.request;
} else {
return {
statusCode: 401,
statusDescription: "Unauthorized",
headers: {
"www-authenticate": { value: 'Basic realm="Application"' },
},
};
}
}

然后,您可以直接在 UI 上进行测试,并假设它可以工作,假设您已经定制了用户名和密码,那么发布该函数。

接下来,打开 CloudFront 发行版并执行以下操作:

  1. 确保原始文件中的 S3 bucket 被配置为 REST 端点,而不是网站端点,也就是说,它必须在 .s3.amazonaws.com上结束,并且在主机名中没有单词 website
  2. 同样在 Origin 设置中,在“ S3 bucket access”下,选择“ Yes use OAI (bucket 可以限制对 CloudFront 的访问)”。在下面的设置中点击“创建 OAI”来创建一个新的 OAI (除非你有一个现有的并且知道你在做什么)。然后选择“ Yes,update the bucket policy”以允许 AWS 向您的 OAI 添加必要的权限。
  3. 最后,打开 CloudFront 发行版的 Behavior 并滚动到底部。在“函数关联”下,对于“查看者请求”,选择“ CloudFront 函数”并选择您新创建的 CloudFront 函数。保存您的更改。

应该就是这样了。如果运气好的话,只需要几分钟(我知道实际上更多) ,而且一旦这些都设置好了,就不会有额外的复杂性了。