【问题标题】:Boto3 IAM User creation failing with InvalidClientTokenId - The security token included in the request is invalidBoto3 IAM 用户创建失败并出现 InvalidClientTokenId - 请求中包含的安全令牌无效
【发布时间】:2019-01-16 10:14:21
【问题描述】:

当我这样做时:

session1 = boto3.session.Session(profile_name='my_profile')
iam_client = session1.client('iam')

鉴于user='an_existin_iam_user',以下成功,因为我可以成功打印accessKeyId和accessKeySecret。

responseCreateAccessKey = iam_client.create_access_key(UserName=user)
accessKeyId = responseCreateAccessKey.get('AccessKey').get('AccessKeyId')
accessKeySecret = responseCreateAccessKey.get('AccessKey').get('SecretAccessKey')

因此,我可以使用 iam_client 为其他用户创建访问凭证(假设 my_profile AWS 配置文件拥有管理员 IAM 用户的凭证)

现在,使用上面新创建的凭证,我想创建一个新的 IAM 用户。以下是我尝试实现的目标:

尝试 1

temp_session = boto3.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')

尝试 2

temp_iam_client = boto3.client('iam',aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')

尝试 3

temp_session = boto3.session.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')

尝试 4(也如以下答案之一所建议的那样)

temp_session = boto3.session.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
time.sleep(5)
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')

以上每一项都失败并出现以下错误

调用 CreateUser 操作时发生错误(InvalidClientTokenId):请求中包含的安全令牌无效。

这里有什么我遗漏的吗? 我要做的就是使用(如上所示)新生成的访问凭据(访问密钥和访问密钥)创建一个新用户。 如果我收到AccessDeniedexception 也没关系。我期待对于没有正确权限的用户。但是InvalidClientTokenId 异常是我不明白为什么我什至得到它的原因。

另外,如果有帮助,我正在尝试在超过 100 个用户的迭代循环中执行此操作(创建访问密钥和秘密,然后使用它来创建新用户)。 (当然,循环处理当前正在处理的用户的访问密钥已经被最大化等情况。) 例如,如果我尝试从 ipython 控制台执行上述用户创建操作,单独为用户说 existing-test-user,那么我会得到正确的 AccessDenied 异常。但是,当循环到达该用户名时(例如在迭代最初的几个用户之后),我会得到 InvalidClientTokenId 异常。

另外一点是通过this get_credentials() 部分,我只是想知道它是否与凭据缓存有关?

【问题讨论】:

    标签: amazon-web-services aws-sdk boto3 aws-iam


    【解决方案1】:

    AWS IAM API 采用最终一致的模型,因此在更新 IAM 资源(例如创建访问密钥)期间会发生延迟。这意味着即使创建 AWS 访问密钥的函数调用成功,也不一定意味着 AWS 访问密钥已立即在 AWS 服务器上完成创建。 https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency

    新答案

    使用backoff,我们可以设置重试策略,以便在超时时使用新创建的 AWS 访问密钥创建 IAM 用户:

    import boto3
    import botocore
    import backoff
    
    
    @backoff.on_exception(backoff.expo, botocore.exceptions.ClientError, max_time=30)
    def create_user(access_key_id, access_key_secret, username):
        temp_session = boto3.Session(aws_access_key_id=access_key_id,aws_secret_access_key=access_key_secret,region_name='ap-southeast-1')
        temp_iam_client = temp_session.client('iam')
        temp_iam_client.create_user(UserName=username)
    
    
    session = boto3.session.Session(profile_name='default')
    iam_client = session.client('iam')
    
    response_access_key = iam_client.create_access_key(UserName='user')
    access_key_id = response_access_key.get('AccessKey').get('AccessKeyId')
    access_key_secret = response_access_key.get('AccessKey').get('SecretAccessKey')
    create_user(access_key_id, access_key_secret, 'my-new-user')
    

    旧答案

    在创建 AWS 访问密钥之后添加睡眠是一种解决方法。

    import boto3
    import time
    session1 = boto3.session.Session(profile_name='my_profile')
    iam_client = session1.client('iam')
    
    responseCreateAccessKey = iam_client.create_access_key(UserName=user)
    accessKeyId = responseCreateAccessKey.get('AccessKey').get('AccessKeyId')
    accessKeySecret = responseCreateAccessKey.get('AccessKey').get('SecretAccessKey')
    
    time.sleep(10)
    temp_session = boto3.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
    temp_iam_client = temp_session.client('iam')
    responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')
    

    【讨论】:

    • 我有点猜到了,也已经尝试过了,尽管在我的例子中是sleep(5)。很抱歉没有将其作为尝试进行更新,并感谢您指出这一点。但是,这似乎也不起作用,给出了同样的例外,至少有 5 秒的睡眠时间。为了确定,我也试试 10 个。
    • 我也用 sleep(5) 尝试过,但对我来说失败了,所用的时间可能会有所不同,有时可能会超过 10 (我知道它令人毛骨悚然)
    • 嗯,还有其他解决方法吗?就像一个 AWS API 一样,它可以用来检查资源是否实际上是在服务器上创建的。如果有这样的事情,我们可以重试直到完成。怎么说?
    • docs.aws.amazon.com/IAM/latest/UserGuide/… 并没有过多地谈论如何处理延迟。它将责任推到了开发者身上。
    • 我已经用指数退避装饰器更新了答案,不是很漂亮,而是一个更简单的解决方案
    猜你喜欢
    • 1970-01-01
    • 2018-04-09
    • 2020-01-11
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多