简体   繁体   English

使用 IAM 角色时的 AWS boto3 InvalidAccessKeyId

[英]AWS boto3 InvalidAccessKeyId when using IAM role

I upload to and download from S3 with a presigned post/url.我使用预先签名的帖子/网址上传到 S3 并从 S3 下载。 The presigned url/post are generated with boto3 in the Lambda function (it is deployed with zappa).预签名的 url/post 使用 Lambda function 中的 boto3 生成(它与 zappa 一起部署)。

While I add my AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID as env variable works perfectly.当我添加我的AWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY_ID作为环境变量时,效果很好。 Then I removed my credentials and I add an IAM role to lambda to full access to S3 bucket.然后我删除了我的凭证,并将一个 IAM 角色添加到 lambda 以完全访问 S3 存储桶。 After that the lambda return with the presigned URL and getObject is working well, however when i want to upload object through the URL, it returns an InvalidAccessKeyId error. After that the lambda return with the presigned URL and getObject is working well, however when i want to upload object through the URL, it returns an InvalidAccessKeyId error. The used key id ASIA... which means those are temporary credentials.使用的密钥 ID ASIA...这意味着这些是临时凭证。

It seems that the lambda does not use IAM role, or what is the problem?好像 lambda 没有使用 IAM 角色,还是有什么问题?

class S3Api:

    def __init__(self):
            self.s3 = boto3.client(
                's3',
                region_name='eu-central-1'
            )

    def generate_store_url(self, key):
        return self.s3.generate_presigned_post(FILE_BUCKET,
                                               key,
                                               Fields=None,
                                               Conditions=None,
                                               ExpiresIn=604800)

    def generate_get_url(self, key):
        return self.s3.generate_presigned_url('get_object',
                                              Params={'Bucket': FILE_BUCKET,
                                                      'Key': key},
                                              ExpiresIn=604800)

My result for sts:getCallerIdentity :我的sts:getCallerIdentity结果:

{
     'UserId': '...:dermus-api-dev',
     'Account': '....',
     'Arn': 'arn:aws:sts::....:assumed-role/dermus-api-dev-ZappaLambdaExecutionRole/dermus-api-dev',
    'ResponseMetadata': {
        'RequestId': 'a1bd7c31-0199-472e-bff7-b93a4f855450',
        'HTTPStatusCode': 200,
        'HTTPHeaders': {
            'x-amzn-requestid': 'a1bd7c31-0199-472e-bff7-b93a4f855450',
            'content-type': 'text/xml',
            'content-length': '474',
            'date': 'Tue, 09 Mar 2021 08:36:30 GMT'
        },
        'RetryAttempts': 0
    }
}

dermus-api-dev-ZappaLambdaExecutionRole role is attached to dermus-api-dev lambda. dermus-api-dev-ZappaLambdaExecutionRole 角色附加到 dermus-api-dev lambda。

Presigned URLs and the Lambda credentials work in a non-obvious way together.预签名 URL 和 Lambda 凭据以一种不明显的方式协同工作。

From the docs , emphasis mine:文档中,强调我的:

  • Anyone with valid security credentials can create a presigned URL.任何拥有有效安全凭证的人都可以创建一个预签名的 URL。 However, in order to successfully access an object, the presigned URL must be created by someone who has permission to perform the operation that the presigned URL is based upon.但是,为了成功访问 object,预签名 URL 必须由有权执行预签名 URL 所基于的操作的人创建。

  • The credentials that you can use to create a presigned URL include:可用于创建预签名 URL 的凭据包括:

    • IAM instance profile: Valid up to 6 hours IAM 实例配置文件:有效期最长为 6 小时

    • AWS Security Token Service: Valid up to 36 hours when signed with permanent credentials, such as the credentials of the AWS account root user or an IAM user AWS Security Token Service:使用永久凭证(例如 AWS 账户根用户或 IAM 用户的凭证)签名后,有效期最长为 36 小时

    • IAM user: Valid up to 7 days when using AWS Signature Version 4 IAM 用户:使用 AWS 签名版本 4 时有效期最长为 7 天

  • To create a presigned URL that's valid for up to 7 days, first designate IAM user credentials (the access key and secret access key) to the SDK that you're using.要创建有效期最长为 7 天的预签名 URL,请首先将 IAM 用户凭证(访问密钥和秘密访问密钥)指定给您正在使用的 SDK。 Then, generate a presigned URL using AWS Signature Version 4.然后,使用 AWS 签名版本 4 生成预签名的 URL。

  • If you created a presigned URL using a temporary token, then the URL expires when the token expires, even if the URL was created with a later expiration time.如果您使用临时令牌创建了预签名的 URL,则 URL 会在令牌到期时到期,即使 URL 是用较晚的到期时间创建的。

Bottom line: The URL might be expired if you wait too long, because the Lambda functions credentials are already expired.底线:如果您等待太久,URL 可能会过期,因为 Lambda 功能凭证已经过期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM