如何增加 boto3.s3.transfer 下载的令牌过期时间?

How do you increase the token expiration time for a boto3.s3.transfer download?

我正在使用 boto3 的 s3.transfer 从 s3 下载几个 4GB 以上的文件。除了一个以外的所有人都能够下载,但是失败的那个给出了以下错误:

ERROR: An error occurred (ExpiredToken) when calling the GetObject operation: The provided token has expired.

我使用它的方式与 http://boto3.readthedocs.org/en/latest/_modules/boto3/s3/transfer.html

中的文档相同
s3_client = session.client('s3')
transfer = S3Transfer(s3_client)
# Download s3://bucket/key to /tmp/myfile
transfer.download_file('bucket', 'key', '/tmp/myfile')

有没有办法增加在 boto3 中使用的已签名 url 的到期时间?

如果相关,我正在使用 Cognito 获取凭据,并与它们一起进行会话

    client = boto3.client('cognito-identity', AWS_REGION)

    # credentials[] contains the IdentityId and Token I get from my server
    # which I get using client.get_open_id_token_for_developer_identity 
    # with TokenDuration=86400
    resp = client.get_credentials_for_identity(IdentityId=credentials['IdentityId'],
                                               Logins={'cognito-identity.amazonaws.com': credentials['Token']})

    # The resp contains the actual temporary AWS secret/access codes and a session token, to be
    # used with the rest of the AWS APIs
    secretKey = resp['Credentials']['SecretKey']
    accessKey = resp['Credentials']['AccessKeyId']
    sessionToken = resp['Credentials']['SessionToken']

    session = Session(aws_access_key_id=accessKey,
                      aws_secret_access_key=secretKey,
                      aws_session_token=sessionToken,
                      region_name=AWS_REGION)

    s3_client = session.client('s3')

您遇到的问题与您假设的 URL 签名的 S3 无关。

Cognito 建立在名为安全令牌服务 (STS) 的 IAM 服务之上。此服务允许通过承担角色(IAM 用户、EC2 实例、Lambda 函数等)或通过提供 Web 身份令牌来生成临时凭证(访问密钥和秘密密钥),用于联合身份方案,使用 Google , Facebook, 亚马逊。

这些凭据在范围(对于您定义的任何 IAM 角色)和时间上都有限制,在 15 秒到几个小时之间,具体取决于用例。

您通过 Cognito 获取的凭据是由 STS 生成的。在低级别,STS API 允许指定您希望这些凭据保持有效的时间(请参阅 http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) . However, I can not find an equivalent in Cognito API (https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)。我很想在这一点上被证明是错误的。

为什么会看到错误?

根据您提供的内容,我的猜测是您的下载代码 运行 比您收到的临时凭证的有效期长。第一次下载可以,后来不行

如何解决?

  • 在低级别,一个干净的解决方案是使用 STS 而不是 Cognito,但是 需要大量的工作,你会失去所有的 使用 Cognito 的好处(跨登录提供商的稳定用户 ID, 多个登录提供商,未经身份验证的用户...)
  • 另一种解决方案,假设您有多个文件传输,在一个循环中,将检查凭据到期时间,并在文件传输之间更新它们。检查 resp['Credentials']['Expiration'] 的到期时间。您可以通过再次调用 get_credentials_for_identity 来更新 Cognito 提供的凭据。
  • 您还可以考虑通过 AWS 提供的 50 多个边缘站点之一下载文件。这是本周刚刚发布的新 S3 功能,可显着加快大文件的上传或下载速度。参见 http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html for more details. There is price tag associated to that usage, see http://aws.amazon.com/s3/pricing/