使用预签名 URL 上传到 Amazon S3 时限制对象大小
Posted
技术标签:
【中文标题】使用预签名 URL 上传到 Amazon S3 时限制对象大小【英文标题】:Limit Size Of Objects While Uploading To Amazon S3 Using Pre-Signed URL 【发布时间】:2014-11-17 10:25:10 【问题描述】:我知道使用这种方法限制对象的上传大小:http://doc.s3.amazonaws.com/proposals/post.html#Limiting_Uploaded_Content
但我想知道如何以 IAM 用户身份在服务器端使用 S3 SDK 生成预签名 url。
这个来自 SDK 的 Url 在其参数中没有这样的选项:http://docs.aws.amazon.com/AWSjavascriptSDK/latest/AWS/S3.html#putObject-property
这两个都不是: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
请注意:我已经知道这个答案:AWS S3 Pre-signed URL content-length 这不是我想要的。
【问题讨论】:
不,我最终改用 S3 策略进行 HTTP POST。 - 链接:docs.aws.amazon.com/AmazonS3/latest/API/… @Koder 您最终是否使用了预签名 URL + HTTP Post 策略的组合?如果是,您可以将其发布为答案吗?对我有帮助! @NikhilPatil - 不知道你所说的组合是什么意思。在上传过程中,我将 http post 策略返回给浏览器。浏览器使用该策略上传文件。当链接文件以供最终用户使用时,我会生成一个预签名的 URL,因为必须保护该文件不被匿名使用(我在生成时配置了 url 超时)。但我在上传过程中不使用预签名的网址。 @Koder 是的,你回答了我的问题 :) 我试图在浏览器上传中使用预签名的 url。并且要限制想要指定策略的大小,是不可能的。即使我已经得出结论,你最终做的是最好的方法。谢谢!这很有帮助 我很惊讶,AWS 没有安排使用预签名 URL 限制最大上传大小 【参考方案1】:对于最终出现在此线程上的任何其他流浪者 - 如果您在从客户端发送请求时设置 Content-Length 属性,则有几种可能性:
Content-Length 是自动计算的,S3 每个文件最多可以存储 5GB
Content-Length 由您的客户端手动设置,这意味着将发生以下三种情况之一:
在任何情况下,恶意用户都可以覆盖您的客户端并手动发送 HTTP 请求,其中包含他们想要的任何标头,包括比您预期的大得多的 Content-Length。签名的 URL 不能防止这种情况!唯一的方法是设置 POST 策略。官方文档:https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html
更多详情:https://janac.medium.com/sending-files-directly-from-client-to-amazon-s3-signed-urls-4bf2cb81ddc3?postPublishedType=initial
或者,您可以使用 Lambda 自动删除比预期大的文件。
【讨论】:
为什么说签名 URL 不能防止更改包含在签名中的标头字段? @user1055568 因为即使您在创建签名 URL 时指定标头作为参数,它仍然会接受没有匹配标头的请求。可以看详细解释here。 我相信你是不正确的。 V4 签名协议允许在签名中包含 ContentLength。可能有些库不支持这个,提醒大家注意一下。 @user1055568 是的,您可以将 ContentLength 作为参数包含在内,对此我不同意您的看法。我具体说的是强制 ContentLength。因此,即使在创建预签名 S3 URL 期间,您可以包含 ContentLength,并且它将在标头映射中返回指定的 ContentLength,但没有什么可以阻止客户端覆盖 ContentLength 标头并将其发送到您的预签名 URL,这将使用覆盖的 ContentLength 处理请求。我建议您尝试使用 Postman 来说服自己。祝你好运! :) 您用于创建签名的工具必须被破坏,因为它不包括签名中的 ContentLength。建议您查看有关如何在签名中包含标头的 Amazon 文档。【参考方案2】:您可能无法事前限制内容上传大小,尤其是考虑到 POST
和 Multi-Part
上传。您可以使用AWS Lambda
创建事后解决方案。您可以设置Lambda
函数来接收来自S3
存储桶的通知,让函数检查对象大小并让函数删除对象或执行其他操作。
这里有一些关于 Handling Amazon S3 Events Using the AWS Lambda.
【讨论】:
对于其他不理解的人:“ex-ante 一词(有时写成 ex ante 或 exante)是一个短语,意思是“在事件发生之前”。【参考方案3】:V4 签名协议提供了在签名中包含任意标头的选项。看: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html 因此,如果您事先知道确切的 Content-Length,则可以将其包含在签名 URL 中。根据 CURL 的一些实验,如果您发送的文件超过 Content-Length 标头中指定的内容,S3 将截断文件。这是一个示例 V4 签名,签名中有多个标头 http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
【讨论】:
如果您发送的 less 比标头中指定的要少,会发生什么?请求是否被接受,如果接受,是否在 S3 上更新内容长度? @julealgon 它将返回 400 错误请求。 ContentLength 通常在发送请求时确定,因此如果您手动指定大于实际文件大小的 ContentLength,S3 会将其视为格式错误的请求。以上是关于使用预签名 URL 上传到 Amazon S3 时限制对象大小的主要内容,如果未能解决你的问题,请参考以下文章
Amazon S3 预签名 URL - 手动或一次性上传无效
如何使用 amazon sdk 为虚域生成预签名的 Amazon S3 url?