我正在使用AWS SDK for PHP来上传和显示来自我的S3存储桶的文件。
这些文件只能通过我的网站访问,不允许其他推荐人 - 没有热链接等。
我还需要能够在存储桶中复制对象。
我正常创建和连接:
$s3Client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'eu-west-2'
]);
$s3 = $s3Client::factory(array(
'version' => 'latest',
'region' => 'eu-west-2',
'credentials' => array(
'provider' => $provider,
'key' => $key,
'secret' => $secret
)
));
并执行Copy object命令:
$s3->copyObject([
'Bucket' => "{$targetBucket}",
'Key' => "{$targetKeyname}",
'CopySource' => "{$sourceBucket}/{$sourceKeyname}",
]);
我尝试了一个策略,使用“如果字符串像引用者”,但AWS然后告诉我,我允许公共访问?!?!?一切正常,即使是copyObject动作,但文件仍然可以直接从任何地方访问!
我尝试使用“Deny if if string not like referrer”,它主要按预期工作 - 我可以上传和显示文件,并且文件在直接链接时不显示(这是我想要的) - 但是,copyObject操作不再有效我得到访问被拒绝错误。
我已经尝试了一切我能想到的,花了几个小时谷歌搜索和寻找答案但无济于事。
这是每个单独的政策......
如果字符串LIKE引用,则仅允许文件访问(GetObject):
{
"Version": "2008-10-17",
"Id": "",
"Statement": [
{
"Sid": "Deny access if referer is not my site",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::MY-BUCKET/*"
],
"Condition": {
"StringLike": {
"aws:Referer": [
"http://MY-SITE/*",
"https://MY-SITE/*"
]
}
}
}
]
}
结果:uploads和copyObject工作但文件仍可在任何地方访问
DENY ALL ACTIONS(*)if string NOT LIKE referrer:
{
"Version": "2008-10-17",
"Id": "",
"Statement": [
{
"Sid": "Deny access if referer is not my site",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::MY-BUCKET/*"
],
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://MY-SITE/*",
"https://MY-SITE/*"
]
}
}
}
]
}
结果:copyObject操作不再有效,我得到访问被拒绝错误
AWS可能会警告您它是公开的,因为出于所有实际目的,它仍然是公开的。
警告
应谨慎使用此密钥:
aws:referer
允许Amazon S3存储桶拥有者帮助防止未经授权的第三方网站将其内容提供给标准Web浏览器。 [...]由于aws:referer
值是由HTTP头中的调用者提供的,未经授权的各方可以使用修改的或自定义的浏览器来提供他们选择的任何aws:referer值。因此,不应使用aws:referer来防止未经授权的方提出直接的AWS请求。它仅用于允许客户保护其存储在Amazon S3中的数字内容不被未经授权的第三方网站引用。https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html
如果您对这种原始机制没有问题,请使用它,但要注意它所做的只是信任浏览器所声称的内容。
这是你的copyObject()
的问题 - 请求不是由浏览器发出的,所以没有Referer
标头来验证。
你可以使用StringLikeIfExists
条件测试Deny
只有错误的引用者(忽略没有引用者,如同对象副本一样)或者 - 更好 - 只需授予s3:GetObject
StringLike
你的引用者,理解公共警告是正确的 - - 这允许未经身份验证的访问,这是引用者检查所涉及的内容。如果从其他网站进行热链接,您的内容仍然可以公开访问,但不能从标准的,未经修改的Web浏览器访问。
为了更好的安全性,您需要使用预先签名的URL(具有较短的到期时间)为您的S3资产呈现HTML,或者使用Amazon Cognito进行完整和正确的授权。
默认情况下,Amazon S3中的对象是私有的。除非以某种方式授予(例如,在IAM用户,IAM组或S3存储桶策略上),否则无法访问。
上述策略都是拒绝策略,可以覆盖允许策略。因此,它们不是可以获取某些东西的原因。
您应首先发现授予访问权限的内容,然后删除该访问权限。一旦对象再次处于私有状态,您应该使用Allow
语句创建一个Bucket Policy,以定义允许访问的情况。