【问题标题】:Verify AWS Credentials with boto3使用 boto3 验证 AWS 凭证
【发布时间】:2020-05-28 18:51:25
【问题描述】:

我正在尝试编写使用许多不同 AWS 密钥的 Python 代码,其中一些可能已过期。给定一个 AWS 密钥对作为字符串,我需要使用 boto3 检查给定的密钥对是否有效。我宁愿不必做任何事情,比如使用 os.system 来运行

echo "$aws_key_id
$aws_secret_key\n\n" | aws configure

然后读取aws list-buckets.的回复

答案应该类似于

def check_aws_validity(key_id, secret):
    pass

其中key_idsecret 是字符串。

请注意,这不是 Verifying S3 credentials w/o GET or PUT using boto3 的重复,因为我在 boto3.profile 中没有密钥。

提前致谢!

编辑 从 John Rotenstein 的回答中,我得到了以下功能。

def check_aws_validity(key_id, secret):
    try:
        client = boto3.client('s3', aws_access_key_id=key_id, aws_secret_access_key=secret)
        response = client.list_buckets()
        return true

    except Exception as e:
        if str(e)!="An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records.":
            return true
        return false

【问题讨论】:

  • 到目前为止你写了什么?你解决问题的方法是什么?
  • 答案就在我的问题中。

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


【解决方案1】:

确实存在这样的凭证验证方法;这是STS GetCallerIdentity API 调用 (boto3 method docs)。

使用过期的临时凭证:

>>> import boto3
>>> sts = boto3.client('sts')
>>> sts.get_caller_identity()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jantman/venv/lib/python3.8/site-packages/botocore/client.py", line 276, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/jantman/venv/lib/python3.8/site-packages/botocore/client.py", line 586, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ExpiredToken) when calling the GetCallerIdentity operation: The security token included in the request is expired

使用无效凭据:

>>> import boto3
>>> sts = boto3.client('sts')
>>> sts.get_caller_identity()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jantman/venvs/current/lib/python3.8/site-packages/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/jantman/venvs/current/lib/python3.8/site-packages/botocore/client.py", line 626, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid

使用有效凭据(ID 替换为 X):

>>> import boto3
>>> sts = boto3.client('sts')
>>> sts.get_caller_identity()
{'UserId': 'AROAXXXXXXXXXXXXX:XXXXXXX', 'Account': 'XXXXXXXXXXXX', 'Arn': 'arn:aws:sts::XXXXXXXXXXXX:assumed-role/Admin/JANTMAN', 'ResponseMetadata': {'RequestId': 'f44ec1d9-XXXX-XXXX-XXXX-a26c85be1c60', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'f44ec1d9-XXXX-XXXX-XXXX-a26c85be1c60', 'content-type': 'text/xml', 'content-length': '426', 'date': 'Thu, 28 May 2020 10:45:36 GMT'}, 'RetryAttempts': 0}}

无效凭据会引发异常,而有效凭据不会,因此您可以执行以下操作:

import boto3
sts = boto3.client('sts')
try:
    sts.get_caller_identity()
    print("Credentials are valid.")
except boto3.exceptions.ClientError:
    print("Credentials are NOT valid.")

【讨论】:

  • 这里的例外应该是botocore.exceptions.ClientError,但如果(例如)访问 macOS 钥匙串凭据被拒绝,也可以获得botocore.exceptions.CredentialRetrievalError。这将由client() 调用触发。
【解决方案2】:

您可以通过直接指定凭据来拨打电话:

import boto3

client = boto3.client('s3', aws_access_key_id='xxx', aws_secret_access_key='xxx')
response = client.list_buckets()

然后您可以使用响应来确定凭据是否有效。

但是,用户可能拥有有效凭据,但没有调用list_buckets() 的权限。这可能会使确定他们是否具有有效凭据变得更加困难。您需要尝试各种组合来查看将什么响应发送回您的代码。

【讨论】:

  • 我知道,如果在命令行中密钥无效,用户将收到 InvalidAccessKeyId 错误。 boto3中是否有相关异常?
  • 是的。尝试使用有效凭据、无效凭据和“未经允许调用 list-buckets() 的有效凭据”的各种组合的代码来查看返回的错误。
  • 如果有一个通用的client.validate_credentials()函数就好了。
  • @keithpjolley 不一定。拥有功能可能是一件好事,但可能会导致安全风险。如果存在这样的方法,它可能在对手找到一对信任的情况下为对手带来更好的侦察。
  • 或者,如果您丢失了钥匙,请更换您的锁。
猜你喜欢
  • 2019-09-12
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多