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

时间:2016-04-20 21:38:02

标签: amazon-web-services amazon-s3 boto3

我正在使用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中使用的签名网址的到期时间?

如果它是相关的,我使用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')

1 个答案:

答案 0 :(得分:3)

您遇到的问题未与您假设的S3签名网址相关联。

Cognito构建于名为Security Token Service(STS)的IAM服务之上。此服务允许通过假设角色(IAM用户,EC2实例,Lambda函数等...)或通过提供Web身份令牌来生成临时凭证(访问密钥和密钥),用于联合身份方案,使用Google,Facebook,Amazon

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

您通过Cognito获取的凭据由STS生成。在较低级别,STS API允许指定您希望这些凭据保持有效的时间长度(请参阅http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)。但是,我在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。该用法与价格标签相关联,请参阅http://aws.amazon.com/s3/pricing/