Amazon S3 - ERR_INSECURE_RESPONSE

时间:2016-02-15 14:13:13

标签: angularjs amazon-web-services angular-file-upload

这个问题已经被问到here但是这个答案对我没有帮助,因为我知道网址是正确的,因为它指向美国标准网址,详见亚马逊指南here < / p>

所以我试图通过角度库 ng-file-upload 将文件上传到我的存储桶。我相信我已经正确设置了桶:

  • 水桶名称为 ac.testing
  • 此CORS配置:

    <?xml version="1.0" encoding="UTF-8"?>
      < CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
      < CORSRule>
        < AllowedOrigin>*</AllowedOrigin>
        < AllowedMethod>POST</AllowedMethod>
        < AllowedHeader>*</AllowedHeader>
      < /CORSRule>
    < /CORSConfiguration>
    

我必须在上面的开口括号后放一个空格,因为如果我不这样做,我就不会添加它。

我已经理解为从任何位置允许POSTS而不管标题 - 这是正确的吗?

我制定的政策:

{
    "Version": "2012-10-17",
    "Id": "Policy<numbers>",
    "Statement": [
        {
            "Sid": "Stmt<numbers>",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::ac.testing/*"
        }
    ]
}

最后 - 在我尝试上传的实际代码中:

      var policy = {
        "expiration": "2020-01-01T00:00:00Z",
        "conditions": [
          {"bucket": "ac.testing"},
          ["starts-with", "$key", ""],
          {"acl": "private"},
          ["starts-with", "$Content-Type", ""],
          ["starts-with", "$filename", ""],
          ["content-length-range", 0, 524288000]
        ]
      }

      var uploadDetails = {
        url: 'https://ac.testing.s3.amazonaws.com/',
        method: 'POST',
        data: {
          key: file.name, 
          acl: 'public-read', 
          // application/octet-stream is the default format used by S3
          'Content-Type': file.type != '' ? file.type : 'application/octet-stream', 
          AWSAccessKeyId: '<my-access-key-id>',
          policy: policy, 
          signature: '<my-access-signature>',
          filename: file.name, 
        },
        file: file
      };


      if (file) {
        // Upload to Amazon S3
        file.upload = Upload.upload(uploadDetails).then(function(success) {
          console.log(JSON.stringify(success) );
        },function(error) {
          console.log(error);
        },function(progress) {
          console.log(JSON.stringify(progress) );
        });
      }  

那我在哪里错了?

编辑

我没有做的一些事情是根据Base64编码对策略和签名进行编码。

该过程涉及对策略进行编码,然后使用生成的代码以及AWS Secret Access Key生成SHA-1 HMAC代码。即使在此之后它仍然会返回相同的错误。

我还为存储桶添加了另一个权限。它匹配此处已定义的策略和CORS设置,但定义为每个人:

Permission

编辑2

我创建了一个名为 ac-k24-uploads 的新存储桶,并更新了与此匹配的网址:

uploadDetails = {
    url: 'https://ac-k24-uploads.s3.amazonaws.com/',

现在出现的错误是:

enter image description here

编辑3

环顾四周似乎亚马逊不喜欢的标题被添加到请求中。我尝试在ng-file-uploads上运行,但是在我自己的机器上却没有。对此的修复似乎是删除这些标题:

method: 'POST',
  headers: {
    'Authorization': undefined
  },

但我仍然得到同样的错误。为什么这些标题会附加到此请求?

编辑4

即使上面的代码仍然在不同的位置添加标题,所以我找到它并删除它们。我现在收到的错误是:

enter image description here

2 个答案:

答案 0 :(得分:8)

这与CORS无关。

这是因为您的桶名称中的点。

如果你的存储桶确实符合美国标准(example-bucket.s3.amazonaws.com不一定是&#34;美国标准&#34;网址),那么这就是你需要的:

var uploadDetails = {         网址:&#39; https://s3.amazonaws.com/ac.testing/&#39;,    ...

这称为基于路径或路径样式的URL,其中存储区表示为路径的第一个元素,而不是将其包含在主机名中。

如果存储桶名称有一个点,则必须这样做;对于不在美国标准中的存储桶,s3.需要s3-region.

这是通配符SSL / TLS证书的限制。 S3提供了对*.s3[-region].amazonaws.com有效的证书,并且此类证书的规则规定* 不能匹配点...因此证书被认为是无效的,因此它是&#39;是一个不安全的回应。&#34;

或者,只需使用短划线而不是点创建一个存储桶,您的代码应该按原样运行。

由于您使用的是Signature V2,因此主机名构造会为其他相同的请求生成相同的签名。 Sig V4不适用。

答案 1 :(得分:1)

实际问题有两个:

  • 标题不正确为&#34; 授权&#34;即使从代码的Upload.upload部分删除它,标题仍然存在。 为了解决这个问题,我不得不从我的api.injector代码中删除该对象 - 这就是它被添加的地方。

    delete config.headers['Authorization']
    
  • 从EDIT3开始,我生成的签名是错误的 - 所以我不得不重新生成它。

感谢迈克尔的帮助。