当前位置: 首页 > 知识库问答 >
问题:

Boto3 STS与MFA工作示例

章嘉致
2023-03-14

我做错了什么?我可以通过aws cli以及boto(如果我使用):

boto3.setup_default_session(profile_name="ROLE_TO_ASSUME")

我想做的是:我有很多AWS帐户,我的脚本需要在其中运行。我厌倦了每次需要在不同的配置文件/角色上运行脚本时都键入mfa。

我收到以下代码的错误消息:

 User: arn:aws:iam::<management account>:user/Ops/<my user> is not authorized to perform: sts:AssumeRole on resource

我们的AWS是这样设置的:我是一个用户,是管理帐户组的一部分。该组与每个帐户上的角色\u建立了信任关系。

下面是我的python:

import boto3

def main():
    boto3.setup_default_session(profile_name="default")
    ec2 = boto3.client('ec2')
    get_assumerole_credentials('arn:aws:iam::<REPLACE WITH ACCOUNTID>:role/ROLE_TO_ASSUME')

def get_assumerole_credentials(arn):
    sts_client = boto3.client('sts')
    # Use client object and pass the role ARN
    assumedRoleObject = sts_client.assume_role(RoleArn=arn,

RoleSessionName="AssumeRoleCredstashSession1")
    credentials = assumedRoleObject['Credentials']
    return dict(aws_access_key_id=credentials['AccessKeyId'],
            aws_secret_access_key=credentials['SecretAccessKey'],
            aws_session_token=credentials['SessionToken'])

if __name__ == "__main__":
    main()

这是我的配置

[profile default]
region = us-west-2
output = json
aws_access_key_id=<censored>
aws_secret_access_key=<censored>

[profile ROLE_TO_ASSUME]
region = us-west-2
source_profile = default
role_arn = arn:aws:iam::<accountid>:role/ROLE_TO_ASSUME
mfa_serial = arn:aws:iam::<accountid>:mfa/<my_user>

根据第一次回复进行编辑:
要清楚,如果我指定“profile”参数,我可以担任角色,如下例所示:

boto3.setup_default_session(profile_name='ROLE_TO_ASSUME')
ec2 = boto3.resource('ec2', region_name='us-west-1')

但是我需要在脚本中使用boto3的STS来获取临时凭据,并在其中扮演一个角色。
我注意到,当我使用boto3的STS承担角色连接方法时,没有MFA提示。

共有3个答案

傅啸
2023-03-14
import boto3

# Prompt for MFA time-based one-time password (TOTP)
mfa_TOTP = raw_input("Enter the MFA code: ")

def role_arn_to_session(**args):
    """
    Usage :
        session = role_arn_to_session(
            RoleArn='arn:aws:iam::<ACCOUNT_NUMBER>:role/example-role',
            RoleSessionName=<'SESSION_NAME'>,
            SerialNumber='<ARN_OF_MFA_DEVICE',
            TokenCode=mfa_TOTP)
        client = session.client('ec2')
    """
    client = boto3.client('ec2')
    response = client.assume_role(**args)
    return boto3.Session(
        aws_access_key_id=response['Credentials']['AccessKeyId'],
        aws_secret_access_key=response['Credentials']['SecretAccessKey'],
        aws_session_token=response['Credentials']['SessionToken'])
哈烨熠
2023-03-14

我想下面的方法对你来说很好

boto3.setup_default_session(profile_name='ROLE_TO_ASSUME')
ec2 = boto3.resource('ec2', region_name='us-west-1')

因此,要获得STS临时凭据,请执行以下操作

boto3.setup_default_session(profile_name='ROLE_TO_ASSUME')
session = boto3.session.Session()
temp_credentials = session.get_credentials().get_frozen_credentials()

注意:如果第一个假设工作正常,这与MFA无关。

如果您正在寻找担任MFA角色,请参阅担任MFA角色http://boto3.readthedocs.io/en/latest/reference/services/sts.html#STS.Client.assume_role

方航
2023-03-14

此处的所有其他解决方案都不会刷新假定的凭据。但它们确实会过期(默认情况下15分钟内,但在执行AssumeRole调用时,您可以将其设置得更长,默认情况下,直到当前会话的最大API会话持续时间为1小时)。

如果您需要自动刷新凭据,我将在这里分享我在研究boto的代码并尝试解决boto对文件系统和配置文件的依赖性几个小时后编写的代码

在这里,我只是使用内置的boto的机制缓存和定期刷新假定的凭据,而不接触任何文件:

from datetime import datetime

import boto3
from botocore.credentials import (
    AssumeRoleProvider,
    AssumeRoleCredentialFetcher,
    DeferredRefreshableCredentials,
    CredentialResolver
)
from dateutil.tz import tzlocal


class RamAssumeRoleProvider(AssumeRoleProvider):
    """
    Overrides default AssumeRoleProvider to not use profiles from filesystem.
    """

    def __init__(self,
                 source_session: boto3.Session,
                 assume_role_arn: str,
                 expiry_window_seconds: int):
        super().__init__(
            load_config=lambda: source_session._session.full_config,
            client_creator=source_session._session.create_client,
            cache={},
            profile_name='not-used'
        )
        self.expiry_window_seconds = expiry_window_seconds
        self.source_session = source_session
        self.assume_role_arn = assume_role_arn
        assert assume_role_arn, "assume_role_arn is required"

    def load(self):
        fetcher = AssumeRoleCredentialFetcher(
            client_creator=self.source_session._session.create_client,
            source_credentials=self.source_session.get_credentials(),
            role_arn=self.assume_role_arn,
            expiry_window_seconds=self.expiry_window_seconds,
            cache=self.cache,
        )

        return DeferredRefreshableCredentials(
            method=self.METHOD,
            refresh_using=fetcher.fetch_credentials,
            time_fetcher=lambda: datetime.now(tzlocal())
        )


def get_assume_role_session(
    source_session: boto3.Session,
    assume_role_arn: str,
    expiry_window_seconds=15 * 60
) -> boto3.Session:
    """
    Creates a new boto3 session that will operate as of another user.

    Source session must have permission to call sts:AssumeRole on the provided ARN,
    and that ARN role must have been trusted to be assumed from this account (where source_session is from).

    See https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html

    Uses internal session._session to hack it together, as I haven't found another way.
    """
    # must have .load() method to be used in CredentialsResolver.
    provider = RamAssumeRoleProvider(
        source_session=source_session,
        assume_role_arn=assume_role_arn,
        expiry_window_seconds=expiry_window_seconds
    )

    # must have .load_credentials() method to be used in register_component()
    resolver = CredentialResolver([provider])
    new_session = boto3.Session()
    new_session._session.register_component('credential_provider', resolver)
    return new_session
 类似资料:
  • aws-mfa: Easily manage your AWS Security Credentials when using Multi-Factor Authentication (MFA) aws-mfa makes it easy to manage your AWS SDK Security Credentials when Multi-Factor Authentication (MF

  • temporal.io如何与cadenceworkflow.io?如果根据节奏工作流服务启动一个新项目,应该使用什么?

  • 这是我第一次在Android上使用相机开发,我已经测试了我在链接中找到的相机演示https://thenewcircle.com/s/post/39/using__the_camera_api 但我对这段代码有一些问题:( 首先,这似乎有必要将这一行添加到Preview(上下文上下文)的代码中 (如果我不添加此测试,程序将崩溃) 就在这条线之前 因为setType()调用现在似乎被弃用了(这就是A

  • 我试图实现一个基本的Hibernate示例,但我无法使其工作。 每次我试着运行它,我都会得到: 线程“main”org.hibernate.hibernate.hibernateException:无法在org.hibernate.engine.JDBC.connections.internal.BasicConnectionCreator.createConnection(BasicConnec

  • 问题内容: 我是SQL,PDO和PHP的新手,所以我知道很多人在问自己。还是没什么冒险的……我想结合两个查询的结果,并使用别名使UNION查询的列名相同。我尝试了各种减少操作,直到没有减少的余地为止,我的应用程序需要的实际结果还有很多。我有以下代码,无法考虑为什么它不起作用。 这两个查询都是独立工作的,但是当我将它们与UNION结合使用时,我什么也没得到。任何建议将是最有帮助的。 非常感谢您的期待

  • 前面我们在安装Go的时候看到需要设置GOPATH变量,Go从1.1版本开始必须设置这个变量,而且不能和Go的安装目录一样,这个目录用来存放Go源码,Go的可运行文件,以及相应的编译之后的包文件。所以这个目录下面有三个子目录:src、bin、pkg GOPATH设置 go 命令依赖一个重要的环境变量:$GOPATH Windows系统中环境变量的形式为%GOPATH%,本书主要使用Unix形式,Wi