如何在连接到boto3 S3时指定凭据?

221
在boto中,我过去是这样指定我的凭据来连接S3的:
import boto
from boto.s3.connection import Key, S3Connection
S3 = S3Connection( settings.AWS_SERVER_PUBLIC_KEY, settings.AWS_SERVER_SECRET_KEY )

我可以使用S3执行我的操作(在我的情况下,从存储桶中删除对象)。

使用boto3的所有示例都是这样的:

import boto3
S3 = boto3.resource( 's3' )
S3.Object( bucket_name, key_name ).delete()

我无法指定我的凭据,因此所有尝试都会失败,并显示InvalidAccessKeyId错误。

我该如何使用boto3指定凭据?


这个答案可能会对你有所帮助:https://dev59.com/9FoU5IYBdhLWcg3w9aWi#36913771 - Ilja Everilä
2
请参阅官方文档中的“配置凭证”部分:https://boto3.readthedocs.io/en/latest/guide/configuration.html - Mark B
我发现将其称为“AWS_SERVER_PUBLIC_KEY”非常奇怪。它的名称应该是“访问密钥ID”,与密钥对的公共部分无关。而且,像s3这样的服务访问权限不应该与服务器(主机)访问权限混淆。我建议不要公开此密钥ID(即使单独使用也没用)。 - mathieu
8个回答

339

你可以创建一个会话

import boto3
session = boto3.Session(
    aws_access_key_id=settings.AWS_SERVER_PUBLIC_KEY,
    aws_secret_access_key=settings.AWS_SERVER_SECRET_KEY,
)

然后使用该会话获取S3资源:

s3 = session.resource('s3')

68
为什么他们不把这个作为显而易见的方法记录下来?!!如果有效,我会采用它作为答案。 - Robert Brax
5
如上方评论所述,这实际上在文档中有提到。 - Moot
1
@Moot,我最初想说在文档中找不到这个,但在凭证部分的“警告”部分中指出令牌是可选的。我真的不明白为什么你会费心去做那个。 - JimmyJames
1
@JimmyJames 这个偏离了话题,但是你可以使用 AWS STS 来生成临时凭证(例如,有效期为一小时)。在这种情况下,会需要会话令牌,如果省略它的话是行不通的。 - Alasdair
5
@JimmyJames STS的使用场景是,您从具有有限权限的aws_access_key_idaws_secret_access_key开始。它们不允许您访问S3,但它们允许您扮演角色,以便访问S3。您调用AWS STS来扮演角色,该调用返回一个新的aws_access_key_idaws_secret_access_keyaws_session_token组合(密钥和访问密钥与原始密钥不同)。然后,您可以使用这些凭据创建一个新会话来访问S3。 - Alasdair
显示剩余2条评论

167
您可以直接按以下方式获取新会话的 client
 s3_client = boto3.client('s3', 
                      aws_access_key_id=settings.AWS_SERVER_PUBLIC_KEY, 
                      aws_secret_access_key=settings.AWS_SERVER_SECRET_KEY, 
                      region_name=REGION_NAME
                      )

13
这适用于获取一个s3的客户端,但OP想要一个s3的资源对象 - Alasdair
2
我同意@Alasdair的观点。文档没有展示如何与客户端进行操作,你也没有提供相关信息,所以我不认为这个回答是相关的。 - Cerin
我尝试了这个,但是它给了我“无法定位凭据”的错误。我之前删除了~/.aws文件夹来测试这个,因为我知道boto默认会在那里查找凭据。 - Prathamesh dhanawade
这是正确的答案,也是唯一有效的方法。我不知道你们在说什么,认为这个方法没有用处。使用客户端可以做任何事情,并且每个 AWS 服务都有广泛的文档支持。只需查看 S3:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html - Dan
@Dan,虽然客户端非常有用,但资源上还存在其他限制。例如,客户端一次只能接收1000个对象的信息。 - LotiLotiLoti

18

这篇文章有些老,但我也把它放在这里供参考。boto3.resource只是实现了默认的Session,你可以通过boto3.resource传递session的详细信息。

Help on function resource in module boto3:

resource(*args, **kwargs)
    Create a resource service client by name using the default session.

    See :py:meth:`boto3.session.Session.resource`.

https://github.com/boto/boto3/blob/86392b5ca26da57ce6a776365a52d3cab8487d60/boto3/session.py#L265

你可以看到它只需要与Boto3.Session相同的参数。

import boto3
S3 = boto3.resource('s3', region_name='us-west-2', aws_access_key_id=settings.AWS_SERVER_PUBLIC_KEY, aws_secret_access_key=settings.AWS_SERVER_SECRET_KEY)
S3.Object( bucket_name, key_name ).delete()

14

我想对@JustAGuy的回答进行进一步阐述。我偏爱使用AWS CLI创建配置文件的方法。原因是,有了配置文件,CLISDK将自动在~/.aws文件夹中查找凭据。而且好处是AWS CLI是用Python编写的。

如果您还没有它,可以从pypi获取cli。以下是从终端设置cli的步骤:

$> pip install awscli  #can add user flag 
$> aws configure
AWS Access Key ID [****************ABCD]:[enter your key here]
AWS Secret Access Key [****************xyz]:[enter your secret key here]
Default region name [us-west-2]:[enter your region here]
Default output format [None]:

完成后,您可以访问boto和任何api,无需指定密钥(除非您要使用其他凭据)。


您还可以指定要填充的列:
  • aws configure set aws_access_key_id [****************ABCD]
  • aws configure set aws_secret_access_key [****************xyz]
- mjeday

11
如果您依赖于.aws/credentials存储用户的 id 和 key,系统会自动获取。
例如:
session = boto3.Session(profile_name='dev')
s3 = session.resource('s3')

这将挑选出“dev”配置文件(用户),如果你的“credentials”文件包含以下内容:
[dev]
aws_access_key_id = AAABBBCCCDDDEEEFFFGG
aws_secret_access_key = FooFooFoo
region=op-southeast-2

2

1
添加此代码片段,可以轻松处理在~/.aws/config中定义的多个配置文件。
import boto3


class AwsAccount:
    account_id: str
    session: boto3.Session
    user_arn: str
    user_id: str

    def __init__(self, account_id: str, session: boto3.Session, user_arn: str, user_id: str):
        self.account_id = account_id
        self.session = session
        self.user_arn = user_arn
        self.user_id = user_id

    @staticmethod
    def from_profile_name(profile_name: str):
        session = boto3.Session(profile_name=profile_name)
        identity = session.client('sts').get_caller_identity()

        return AwsAccount(
            account_id=identity['Account'],
            session=session,
            user_arn=identity['Arn'],
            user_id=identity['UserId'],
        )

示例用法:

default_account = AwsAccount.from_profile_name('default')
another_account = AwsAccount.from_profile_name('other')

s3 = default_account.session.client('s3')
s3.delete_object(Bucket='string', Key='string')

0

您可以设置默认的 AWS 环境变量用于密钥和访问密钥 - 这样您就不需要更改默认客户端创建代码 - 但如果您有非默认凭据,最好将其作为参数传递。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接