S3 PUT的Boto generate_url不适用于IAM角色?

Adr*_*aty 5 amazon-s3 boto amazon-web-services amazon-iam

我使用以下Python/Boto代码生成一个到Amazon S3存储桶的一次性文件上传URL:

from boto.s3.connection import S3Connection

def get_signed_upload_url():
    s3 = S3Connection(ACCESS_KEY_ID, SECRET_ACCESS_KEY, is_secure=True)
    return s3.generate_url(300, 'PUT', bucket=BUCKET, key=KEY,
        headers={'Content-Type': 'text/plain'})
Run Code Online (Sandbox Code Playgroud)

它已经运行了好几年了,今天仍在继续.

但是现在,我正在转换为IAM角色 - 这将使我免于硬编码ACCESS_KEY_IDSECRET_ACCESS_KEY.因此,我删除了硬编码密钥,导致此代码:

from boto.s3.connection import S3Connection

def get_signed_upload_url():
    s3 = S3Connection(is_secure=True)
    return s3.generate_url(300, 'PUT', bucket=BUCKET, key=KEY,
        headers={'Content-Type': 'text/plain'})
Run Code Online (Sandbox Code Playgroud)

使用代码,每当我生成一个URL并PUT从我的客户端Web应用程序(通过Ajax)向它发出请求时,我都会收到HTTP 400 Bad Request来自S3 的错误:

<Error>
    <Code>InvalidToken</Code>
    <Message>The provided token is malformed or otherwise invalid.</Message>
    <!-- account-specific stuff removed -->
</Error>
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

一些额外的细节:

  • 这将部署到EC2服务器,该服务器将自动分配其IAM角色.我已经确认该角色的授权可以正确地提供给我的Python代码.我的代码的所有其他部分 - 包括generate_url()生成GETURL的调用- 工作正常,使用ACCESS_KEY_ID自动传递到EC2实例的环境.
  • Python 2.7.9和Boto 2.38.0.
  • IAM角色似乎具有所有适当的权限,我的代码的其他部分使用该角色成功地与S3(获取项目和创建项目)进行交互这一事实证明了这一点.只有这个特殊的东西才PUT行不通.
  • 前端逻辑发送一个Content-Type标头,这就是那个标头在那里的原因.我尝试Content-Type从这个Boto代码和前端逻辑中删除标题,但问题仍然存在.

Adr*_*aty 0

好吧,我花了一年多的时间才弄清楚 \xe2\x80\x94\xc2\xa0 但我终于做到了。

\n\n

问题是我的前端 JavaScriptdecodeURIComponent()在发出 Ajax 请求之前正在调用签名的 URL。

\n\n

在我切换到 IAM 角色之前,这不是问题,因为签名的 URL 中没有任何有趣的字符 \xe2\x80\x94,因此decodeURIComponent()没有任何效果。但 IAM 角色使用不同的签名 URL 语法:查询字符串包含许多斜杠,这些斜杠被decodeURIComponent().

\n\n

希望这对某人有帮助。

\n