Boto3 IAM 用户创建失败,并显示 InvalidClientTokenId - 请求中包含的安全令牌无效

Boto3 IAM User creation failing with InvalidClientTokenId - The security token included in the request is invalid

当我这样做时:

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')

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

An error occurred (InvalidClientTokenId) when calling the CreateUser operation: The security token included in the request is invalid.

这里有我遗漏的东西吗? 我想要做的就是使用(如上所示)新生成的访问凭证(accesskey 和 access secret)创建一个新用户。 如果我得到 AccessDenied 异常也没关系。我希望对于没有正确权限的用户。但是 InvalidClientTokenId 异常是我不明白为什么我什至得到它的东西。

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

另一个注意事项是 this get_credentials() 部分,我只是想知道它是否与凭据缓存有关?

AWS IAM API 采用最终一致的模型,因此在更新 IAM 资源(例如创建访问密钥)期间会发生延迟。这意味着即使创建 AWS Access Key 的函数调用成功,也不一定意味着 AWS Access Key 已立即在 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')