You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用AWS STS AssumeRole的MFA TokenCode批量获取多账号会话?

单MFA验证码批量获取多AWS账号AssumeRole会话

问题背景

使用boto3遍历多个AWS账号,通过AssumeRole获取会话,对应的IAM策略要求MFA验证。现有代码会为每个账号单独执行AssumeRole并传入MFA码,但每次AssumeRole成功后,该MFA码就无法再次使用,必须等待30秒获取新码,效率极低。而AWS控制台仅在登录时要求MFA,切换角色无需重复验证,因此希望实现用单个MFA码完成所有账号的AssumeRole操作。

试错发现:同一个MFA码可重复用于失败的AssumeRole请求(如权限不足报错),但一旦某次AssumeRole成功,该码立即失效。

基础代码如下:

session = boto3.Session(
     aws_access_key_id=#####,
     aws_secret_access_key=#####
     )

sts_client = session.client('sts')
assumed_role = sts_client.assume_role(
     RoleArn=f'arn:aws:iam::#####:role/#####',
     RoleSessionName=f'#####',
     SerialNumber='arn:aws:iam::#####:mfa/#####',
     TokenCode=mfa_code
     )

credentials = assumed_role['Credentials']
assumed_session = boto3.Session(
     aws_access_key_id=credentials['AccessKeyId'],
     aws_secret_access_key=credentials['SecretAccessKey'],
     aws_session_token=credentials['SessionToken']
)

解决方案

核心思路是先通过MFA获取已验证的临时基础会话凭证,之后用该凭证发起所有AssumeRole请求,无需重复传入MFA码,和AWS控制台的逻辑一致。

步骤1:获取带MFA验证的基础临时凭证

调用sts.get_session_token接口,传入MFA信息,获取已完成MFA验证的临时凭证。这个凭证的有效期最长为12小时,期间可用于多次AssumeRole操作。

步骤2:用已验证的凭证创建会话,批量执行AssumeRole

基于上述临时凭证创建boto3会话,后续所有AssumeRole请求都使用该会话的STS客户端,无需再提供MFA参数。

修改后的代码示例

# 1. 用长期密钥创建初始会话
initial_session = boto3.Session(
    aws_access_key_id=#####,
    aws_secret_access_key=#####
)

# 2. 获取带MFA验证的临时基础凭证
sts_initial = initial_session.client('sts')
mfa_verified_creds = sts_initial.get_session_token(
    SerialNumber='arn:aws:iam::#####:mfa/#####',
    TokenCode=mfa_code
)['Credentials']

# 3. 创建已验证的基础会话
verified_session = boto3.Session(
    aws_access_key_id=mfa_verified_creds['AccessKeyId'],
    aws_secret_access_key=mfa_verified_creds['SecretAccessKey'],
    aws_session_token=mfa_verified_creds['SessionToken']
)

# 4. 遍历账号批量执行AssumeRole,无需再传MFA码
account_roles = [
    {'role_arn': 'arn:aws:iam::account1:role/your-role', 'session_name': 'session-account1'},
    {'role_arn': 'arn:aws:iam::account2:role/your-role', 'session_name': 'session-account2'},
    # 更多账号角色...
]

sts_verified = verified_session.client('sts')
assumed_sessions = []
for role in account_roles:
    try:
        assumed_role = sts_verified.assume_role(
            RoleArn=role['role_arn'],
            RoleSessionName=role['session_name']
        )
        assumed_session = boto3.Session(
            aws_access_key_id=assumed_role['Credentials']['AccessKeyId'],
            aws_secret_access_key=assumed_role['Credentials']['SecretAccessKey'],
            aws_session_token=assumed_role['Credentials']['SessionToken']
        )
        assumed_sessions.append(assumed_session)
        print(f"成功获取账号{role['role_arn'].split(':')[4]}的会话")
    except Exception as e:
        print(f"获取账号{role['role_arn'].split(':')[4]}会话失败: {str(e)}")

原理说明

  • get_session_token返回的临时凭证已完成MFA验证,AWS会标记该会话的身份已通过MFA校验,后续基于该会话的AssumeRole请求无需再次验证MFA。
  • 原代码中每次AssumeRole直接用长期密钥发起,必须每次传入MFA码,且成功后AWS会消耗该MFA码(防止重复使用),导致无法复用。

内容的提问来源于stack exchange,提问作者Bryant Eastham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:35:07