python - 使用 Python 生成 Amazon S3 CORS 签名

标签 python cordova amazon-s3 hashlib

让 S3 接受通过 PhoneGap (Cordova) FileTransfer.upload() 生成的 CORS POST 请求的上传真是太糟糕了。对于我可能遗漏的任何建议,我们将不胜感激。目前我使用下面的代码收到 403 AccessDenied 响应。对照S3的文档翻了很多遍,都找不到问题。

这是生成签名的 Python 代码:

# Create policy document for S3.
policy_obj = {"expiration": "2014-01-01T00:00:00Z",
  "conditions": [ 
    {"bucket": "<my.bucket.name>"}, 
    ["starts-with", "$key", "story_"],
    {"acl": "public-read"},
    ["eq", "$Content-Type", "audio/mp4"],
    ["content-length-range", str(0), str(2097152)]
  ]
}

policy = base64.b64encode(json.dumps(policy_obj))

# Create signature for S3
signature = base64.b64encode(
    hmac.new(
        key=app.config['AWS_SECRET_KEY'], 
        msg=policy, 
        digestmod=hashlib.sha1
    ).digest()
)

此过程生成的签名与 S3 Signature Tester 生成的签名匹配(将 base64 策略转换为十六进制,然后使用 key 通过签名测试器运行)。

将生成的策略和签名传递给客户端,并使用此 PhoneGap FileTransfer 调用构建对 S3 的请求:

// Upload file to Amazon S3
// r is the response object generated by Python
var options = new FileUploadOptions();
options.chunkedMode = false;
options.mimeType="audio/mp4";
options.fileKey='file';
options.fileName='story_' + uniqueKey + '.m4a';
options.params={
    "key": "${filename}",
    "acl": "public-read",
    "AWSAccessKeyId": r.aws_access_key,
    "Policy": r.policy,
    "Signature": r.signature,
};

var ft = new FileTransfer();
ft.upload(path, "http://<my.bucket.name>.s3.amazonaws.com/", uploadSuccess, uploadFail, options);

这是 CORS 配置(是的,我打算在上传工作后将其锁定):

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

这是存储桶策略:

{
    "Version": "2008-10-17",
    "Id": "Policy1356975063803",
    "Statement": [
        {
            "Sid": "Stmt1357234455973",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<my.bucket.name>/*"
        },
        {
            "Sid": "Stmt1356975061658",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::293855469575:root"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<my.bucket.name>"
        }
    ]
}

更新:

这是 Python 将对象转换为 JSON 后策略本身的样子:

{
  "conditions": [
    {
      "bucket": "<my.bucket.name>"
    }, 
    [
      "starts-with", 
      "$key", 
      "story_"
    ], 
    {
      "acl": "public-read"
    }, 
    [
      "eq", 
      "$Content-Type", 
      "audio/mp4"
    ], 
    [
      "content-length-range", 
      "0", 
      "6291456"
    ]
  ], 
  "expiration": "2014-01-01T00:00:00Z"
}

最佳答案

您是否尝试删除政策中的换行符?

这是政策的 Ruby 代码,由 s3_file_upload 提供:

Base64.encode64(policy_data.to_json).gsub("\n", "")

请让我知道您是否成功上传,因为我正在尝试做同样的事情。

关于python - 使用 Python 生成 Amazon S3 CORS 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14165921/

相关文章:

python - 如何使用 Python 触发 Azure Runbook

android - 运行 "ionic run android"时 ionic 构建失败

android - Cordova CLI "cordova build android"错误 "Does not appear to be an xcode project, no xcode project file in..."?

ios - 在 XCode 中构建一个完整的 Cordova 应用程序以部署到 TestFlight

java - 如何使用 java 以编程方式在 Amazon S3 存储桶之间传输文件?

javascript - 由于 CORS 访问限制,MediaElementAudioSource 输出零

amazon-s3 - FileZilla Pro 与 S3 使用 STS 凭证

python - 在用户定义类的实例上启用列表(实例)或元组(实例)

python - 如何避免循环依赖?

python - 为什么我的代码会打印 "built-in method"和一些十六进制数字?