AccessDenied Invalid according to Policy: Extra input fields: content-type
当我有这个
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="acl"
public-read
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="awsaccesskeyid"
my-access-key-id
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="bucket"
my-bucket
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="Content-Type"
image/png
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="key"
images/anime_girl.png
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="policy"
my-policy
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="signature"
my-signature
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="success_action_status"
201
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="file"; filename="anime_girl.png"
Content-Type: image/png
但是,如果我在下面的代码中完全省略了Content Type
,则文件会上传但不具备正确的内容类型。
"acl" => "public-read",
"awsaccesskeyid" => $s3->getAwsAccessKeyId(),
"bucket" => $s3->getBucket(),
"Content-Type" => $inputs['type'],
"key" => "images/" . $inputs['name'],
"policy" => $s3->getPolicy(true),
"signature" => $s3->getSignedPolicy(),
"success_action_status" => "201"
我还尝试将内容类型添加到policy
中,我收到此错误
AccessDenied Invalid according to Policy: Policy Condition failed: ["starts-with", "Content-Type", "image/png"]
我尝试了其他一些建议并收到此错误
AccessDenied Invalid according to Policy: Policy Condition failed: ["eq", "Content-Type", "image/png"]
这是我的角色配置
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
那么如何以其他方式指定内容类型或修复此问题?
当我省略任何类型的内容类型时(我没有在后端指定任何内容)我得到了像Ben这样的请求有效负载
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="acl"
public-read
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="awsaccesskeyid"
xxxx
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="bucket"
xxxxx
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="key"
images/Elf-Anime-Warrior-Wallpaper.jpg
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="policy"
xxxx
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="signature"
0BbpI0AP0wL3S1cBfo9n9tOp+N8=
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="success_action_status"
201
------WebKitFormBoundaryUjxIo0gCBYg7AqJt
Content-Disposition: form-data; name="file"; filename="Elf-Anime-Warrior-Wallpaper.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryUjxIo0gCBYg7AqJt--
问题是,在存储桶中,文件的内容类型为binary/octet-stream
,因此图像不会在浏览器中查看,而是会被下载(这不是我的内容)想)。因此,当我的请求有效负载如上所述时,我不确定为什么亚马逊没有正确设置内容类型。
答案 0 :(得分:5)
根据Amazon S3 documentation,您确实可以将Content-Type
作为表单字段传递,但是you need to allow that in your policy。
所以你需要这样的东西:
<强>策略:强>
{
"expiration": "2007-12-01T12:00:00.000Z",
"conditions": [
{"acl": "public-read" },
{"bucket": "johnsmith" },
["starts-with", "$key", "user/eric/"],
["starts-with", "$Content-Type", ""],
...
]
}
此处的相关行是["starts-with", "$Content-Type", ""]
。文档说明类型&#34;的条件匹配任何&#34;应该是&#34;开始 - &#34;空值。如果要将内容类型限制为某种内容,则应使用["starts-with", "$Content-Type", "image/"]
,例如。
<强>形式:强>
(从S3文档中获取的示例,相应地更改值)。
<form action="http://examplebucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="user/user1/${filename}">
<input type="hidden" name="acl" value="public-read">
<input type="hidden" name="success_action_redirect" value="http://examplebucket.s3.amazonaws.com/successful_upload.html">
<input type="hidden" name="Content-Type" value="binary/octet-stream">
<input type="hidden" name="Policy" value='<Base64-encoded policy string>'>
<input type="hidden" name="x-amz-meta-uuid" value="14365123651274">
<input type="hidden" name="X-Amz-Signature" value="<signature-value>">
<input type="hidden" name="X-Amz-Credential" value="AKIAIOSFODNN7EXAMPLE/20130806/us-east-1/s3/aws4_request">
<input type="hidden" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256">
<input type="hidden" name="X-Amz-Date" value="20130806T000000Z">
Tags for File:
<input type="input" name="x-amz-meta-tag" value=""><br>
File:
<input type="file" name="file"><br>
<input type="submit" name="submit" value="Upload to Amazon S3">
</form>
正如您在第一个有效负载中所做的那样,您确实设置了一个&#34; Content-Type&#34;表格的字段。这与更新的政策一起应该有效。
但请注意,如果您事先知道要上传的文件的类型,则应将策略和表单字段都设置为该类型。但是如果要上传不同类型的文件,则将Content-Type条件设置为&#34;匹配任何&#34;在策略中,您可以编写一个简单的javascript来拦截表单的submit
事件,以动态更改Content-Type
字段(此处使用jQuery编写):
$("#s3-form").on("submit", function() {
var contentTypeField = $("input[name='Content-Type']", this),
fileField = $("input[type='file']", this),
selectedFiles = fileField.get(0).files;
if (files.length > 0) {
// we're uploading a single file, so get the type for the first selected file
contentTypeField.val(selectedFiles[0].type);
}
});
答案 1 :(得分:0)
这是我将文件上传到S3时的示例工作请求有效负载:
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="key"
uploads/tmp/dbdfc12f-665e-4389-a739-f345e7acea48/svg_3927.zip
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="AWSAccessKeyId"
xxx
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="acl"
public-read
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="policy"
xxx
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="signature"
xxx=
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="success_action_status"
201
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="file"; filename="svg_3927.zip"
Content-Type: application/zip
正如您所看到的,内容类型最后只与文件数据一起设置了一次。
<强>更新强>
以下是我的开发桶的CORS:
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
<AllowedHeader>*</AllowedHeader>
注意<AllowedHeader>Content-*</AllowedHeader>
,这可能会解决您的问题。
答案 2 :(得分:-1)
尝试在“婴儿车”中抵消ContentType
。级别数组..
"acl" => "public-read",
"awsaccesskeyid" => $s3->getAwsAccessKeyId(),
"bucket" => $s3->getBucket(),
"key" => "images/" . $inputs['name'],
"policy" => $s3->getPolicy(true),
"signature" => $s3->getSignedPolicy(),
"success_action_status" => "201",
// indent "ContentType" within a "params" array
"params" => array(
"ContentType" => $inputs['type']
)