S3:在标题中使用令牌作为一个愚蠢的身份验证令牌

时间:2016-07-14 23:52:28

标签: java amazon-web-services amazon-s3

如果请求附加了令牌,我想授予对S3存储桶的读访问权限。我的AWS策略如下所示:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::some_bucket/*",
            "Condition": {
                "StringEquals": {
                    "aws:principaltype": "authorized_user"
                }
            }
        }
    ]
}

我试图像这样编写链接(在Java中):

fileInfo.add('https://s3.amazonaws.com/some_bucket/' + file + '?aws:principaltype=authorized_user');

但我只是收到了标准访问被拒绝的消息:

<Code>AccessDenied</Code>

我做错了什么?或者有更好的方法来实现伪公共访问设置吗?

1 个答案:

答案 0 :(得分:1)

你不能只弥补condition keys

它们不等同于标题 - 它们中的一些恰好与标题相对应的事实是为了方便而不是必需。

当我看到这样的问题时,我开始怀疑,动机主要是想要避免学习如何以习惯的方式做事,无论出于何种原因。如果您处于一个容易注入请求标头的环境中,那么为什么不生成带有匹配标记的Authorization标头?

在S3中没有像你想象的那样的能力。

如果您要使用原始访问标识在存储桶前配置CloudFront,则可以生成带有通配符的预签名URL ,这样一个预先签名的URL就可以了表示任何或所有桶,例如允许https://example.com/cats/*.jpg允许访问带有S3对象键前缀cats/的JPEG文件。 CloudFront验证通配符签名的URL,然后使用其原始访问标识从S3获取对象。 (S3签名的URL不支持通配符; CloudFront signed URLs do)。

这似乎是一个简单的解决方案。

或者,如果您的应用程序有一个Web服务器,请将请求发送到该服务器,如果需要&#34;令牌&#34;匹配,然后签署URL并返回302重定向,发送浏览器以从S3获取对象。我有几个系统执行此操作,其中一个查找用户的会话cookie内容并将其与对象元数据进行比较,允许生成签名的重定向(如果匹配)(它可以允许用户)基于用户id,用户类id或权限集id来访问对象,在会话中匹配与对象存储的对象;如果访问被拒绝,则返回403;如果对象不存在,则它仍然存在且仍然存在返回403,以便出于安全原因不能扫描存储桶。这个 - 有或没有会话验证,但只是一个令牌的存在 - 也可以用API网关后面的lambda函数来实现......它本身甚至支持令牌(&#34; API密钥。&#34; )