【问题标题】:Boto3 uses old credentialsBoto3 使用旧凭据
【发布时间】:2016-04-27 15:57:03
【问题描述】:

我正在使用tkinter 创建返回安全组的 gui 应用程序。目前,如果您想更改您的凭据(例如,如果您不小心输入了错误的凭据),您必须重新启动应用程序,否则 boto3 将继续使用旧凭据。

我不确定它为什么继续使用旧凭据,因为我正在使用当前输入的凭据再次运行所有内容。

这是设置环境变量并启动boto3 的代码的sn-p。如果您第一次输入正确的凭据,它就可以正常工作。

os.environ['AWS_ACCESS_KEY_ID'] = self.accessKey
os.environ['AWS_SECRET_ACCESS_KEY'] = self.secretKey

self.sts_client = boto3.client('sts')

self.assumedRoleObject = self.sts_client.assume_role(
    RoleArn=self.role,
    RoleSessionName="AssumeRoleSession1"
)

self.credentials = self.assumedRoleObject['Credentials']

self.ec2 = boto3.resource(
    'ec2',
    region_name=self.region,
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken'],
)

凭证变量设置使用:

self.accessKey = str(self.AWS_ACCESS_KEY_ID_Form.get())
self.secretKey = str(self.AWS_SECRET_ACCESS_KEY_Form.get())
self.role = str(self.AWS_ROLE_ARN_Form.get())
self.region = str(self.AWS_REGION_Form.get())
self.instanceID = str(self.AWS_INSTANCE_ID_Form.get())

有没有办法在boto3 中使用不同的凭据而无需重新启动程序?

【问题讨论】:

  • 这是为 boto3 模块分配可变访问权限的错误方法。因为 boto API 将假定并使用缓存的访问密钥 @Vor 答案是告诉 boto 的显式方式。
  • @mootmoot 如果我使用importlib.reload 重新加载模块,它应该“清除”缓存对吗?

标签: python python-3.x amazon-web-services tkinter boto3


【解决方案1】:

您需要 boto3.session.Session 来覆盖访问凭据。

只要这样做 参考http://boto3.readthedocs.io/en/latest/reference/core/session.html

import boto3

# Assign you own access 
mysession = boto3.session.Session(aws_access_key_id='foo1', aws_secret_access_key='bar1')

# If you want to use different profile call foobar inside .aws/credentials
mysession = boto3.session.Session(profile_name="fooboar")

# Afterwards, just declare your AWS client/resource services    
sqs_resource=mysession.resource("sqs")

# or client 
s3_client=mysession.client("s3")

基本上,您的代码几乎没有什么变化。您只需传入会话而不是直接 boto3.client/boto3.resource

self.sts_client = mysession.client('sts')

【讨论】:

    【解决方案2】:

    当然,只需为每组凭据从 botocore.session.Session 对象创建不同的 sessions

    import boto3
    s1 = boto3.session.Session(aws_access_key_id='foo1', aws_secret_access_key='bar1')
    s2 = boto3.session.Session(aws_access_key_id='foo2', aws_secret_access_key='bar2')
    

    您还可以利用 set_credentials 方法来保持 1 个会话即时更改凭据:

    import botocore
    session - botocore.session.Session()
    
    session.set_credentials('foo', 'bar')
    client = session.create_client('s3')
    client._request_signer._credentials.access_key
    u'foo'
    
    session.set_credentials('foo1', 'bar')
    client = session.create_client('s3')
    client._request_signer._credentials.access_key
    u'foo1'
    

    【讨论】:

    • 感谢您的回答!这是一次设置多个会话吗?如果可能,我希望只有 1 个会话并终止旧会话。
    • 我不确定如何实现这一点,因为我不确定role 的设置位置。另外,这是否适用于我当前的代码,还是我必须重写代码的self.ec2 = boto3.resource 部分?
    • boto3.session.Session 示例之后的新代码示例应该可以阐明您的问题。例如s1_s3 = s1.resource("s3")
    【解决方案3】:

    @mootmoot 和@Vor 给出的答案清楚地说明了使用会话处理多个凭据的方式。

    @Vor 的回答

    import boto3
    s1 = boto3.session.Session(aws_access_key_id='foo1', aws_secret_access_key='bar1')
    s2 = boto3.session.Session(aws_access_key_id='foo2', aws_secret_access_key='bar2')
    

    但是你们中的一些人会好奇 为什么 boto3 客户端或资源首先会以这种方式运行?

    让我们澄清一下关于 Session 和 Client 的几点,因为它们实际上会引导我们找到上述问题的答案。

    会话

    • “会话”存储配置状态并允许您创建服务客户端和资源

    客户

    • 如果凭据没有作为参数显式传递给boto3.client 方法,则将自动使用为会话配置的凭据。如果您想覆盖用于此特定客户端的凭据,您只需提供凭据作为参数

    现在让我们来看看代码,看看当你调用boto3.client()时实际发生了什么

    def client(*args, **kwargs):
        return _get_default_session().client(*args, **kwargs)
    
    def _get_default_session():
        if DEFAULT_SESSION is None:
            setup_default_session()
        return DEFAULT_SESSION
    
    def setup_default_session(**kwargs):
        DEFAULT_SESSION = Session(**kwargs)
    

    以上经验教训

    1. 函数boto3.client()实际上只是boto3.Session.client()方法的代理
    2. 如果您曾经使用过客户端,则会设置DEFAULT_SESSION,并且对于下一次连续创建客户端,它将继续使用DEFAULT_SESSION
    3. 如果在创建 boto3 客户端时未将凭据作为参数显式传递,则使用为 DEFAULT_SESSION 配置的凭据。

    回答

    • 第一次调用boto3.client() 设置DEFAULT_SESSION 并使用oldCredsAccessKeyoldCredsSecretKey 配置会话,分别为环境变量AWS_ACCESS_KEY_IDAWS_SECRET_ACESS_KEY 设置值。

    • 因此,即使您在环境中设置了新的凭据值,也就是这样做

    os.environ['AWS_ACCESS_KEY_ID'] = newCredsAccessKey
    os.environ['AWS_SECRET_ACCESS_KEY'] = newCredsSecretKey
    
    • 即将到来的boto3.client() 调用仍会获取为DEFAULT_SESSION 配置的旧凭据

    注意

    • boto3.client() 在整个答案中调用意味着没有参数传递给客户端方法。

    参考文献

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      相关资源
      最近更新 更多