最初,我设置了一个S3存储桶“ bucket.mydomain.com”,并在DNS中使用了CNAME,因此可以从那里拉文件,就好像它是子域一样。这适用于http:
bucket.mydomain.com/image.jpg
或使用https之类的
s3.amazonaws.com/bucket.mydomain.com/image.jpg
此存储桶中的某些文件是公共访问权限,但有些文件是“经过身份验证的读取”,因此,我必须生成一个带有到期时间的签名URL,才能对其进行读取/下载。
我希望能够使用URL中不带亚马逊名称的https,因此我设置了以S3存储桶为源的CloudFront发行版。现在我可以使用https了:
bucket.mydomain.com/image.jpg
我现在遇到的问题是,似乎存储桶中的所有文件都必须公开读取,或者必须进行身份验证才能读取。
如何强制将签名的URL用于某些文件,而将其他文件公开读取?
答案 0 :(得分:0)
似乎我的存储桶中的所有文件都必须公开读取,或者都必须经过身份验证才能读取
至少在一个简单的配置中,这是正确的。
CloudFront具有一项称为原始访问身份(OAI)的功能,该功能使它可以验证发送到您的存储桶的请求。
CloudFront还支持使用CloudFront签名的URL(和签名的cookie)控制查看者对您资源的访问。
但这两个功能是相互独立的。
如果配置了OAI,则始终将身份验证信息发送到存储桶,而不管对象是私有的还是公共的。
类似地,如果为缓存行为启用Restrict Viewer Access,则CloudFront将始终要求对查看器请求进行签名,而不管对象是私有的还是公共的(在存储桶中),因为CloudFront不知道。
有两种选择。
如果按逻辑将内容按路径分开,则解决方案很简单:创建多个具有匹配的路径模式(例如/public/*
或/private/*
)的缓存行为,并为它们配置单独的适当的“限制查看者访问权限”设置。对象在存储桶中是否公开无关紧要,因为如果该缓存行为未“限制查看者访问”,CloudFront会传递对(例如)/public/*
的请求而无需签名URL。默认情况下,您可以创建25个唯一的缓存行为路径模式。
如果这不是解决方案,则可以创建两个CloudFront分配。一种可能是没有OAI,也没有启用“限制查看器访问权限”。此分发只能获取公共对象。第二个发行版将具有OAI,并且需要签名的URL。您可以将其用于私有对象(它也可以用于公共对象,但是它们仍然需要签名的URL)。这里没有价格差异,但是您可能有跨域问题需要解决。
或者,您可以修改应用程序以在呈现HTML时(或API响应或链接的任何上下文)对所有URL签名,以获取其他公共内容。
或者,根据平台的体系结构,可能还有其他更复杂的方法可能有意义,这取决于公共和私有的混合以及您是否愿意使用Lambda @ Edge触发器在边缘添加一些智能,可以执行诸如检查/修改飞行中的请求,查询外部逻辑和数据源(例如在DynamoDB中查找会话cookie),拦截错误并生成重定向之类的事情。
答案 1 :(得分:0)
迈克尔的描述很好。亚马逊还表示(下面的链接)“不赞成使用签名版本2,对签名版本2的最终支持将于2019年6月24日终止。”
https://docs.aws.amazon.com/AmazonS3/latest/dev/auth-request-sig-v2.html