使用EC2 Metadata IAM凭证调用AWS API出现dict对象不可调用报错
报错原因
- requests库的
auth参数要求传入实现了签名逻辑的可调用对象,你当前直接传入了get_auth_token()返回的原始IAM凭证字典,requests尝试调用该字典对象完成签名时触发了类型错误。 - 你已经导入了专门用于AWS请求SigV4签名的
AWSRequestsAuth类,但代码中没有使用该类对凭证做封装。
修复方案
直接修复现有逻辑
你需要将获取到的原始凭证传入AWSRequestsAuth构造签名对象,再传给requests的auth参数,示例修改如下:
# 原有获取凭证逻辑不变 credentials = get_auth_token() # 新增:构造AWS签名对象,替换参数为你实际的API对应值 auth = AWSRequestsAuth( aws_access_key=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_token=credentials['Token'], aws_host='你的API域名,例:xxx.execute-api.cn-north-1.amazonaws.com.cn', aws_region='AWS区域编码,例:cn-north-1、us-east-1', aws_service='AWS服务编码,调用API网关填execute-api,其他服务对应替换' ) # 后续requests请求逻辑不变 response = requests.request(method,jsonInput['url'],auth=auth, data=body,headers=headers)
优化建议(推荐)
不要手动请求EC2元数据获取凭证,直接使用boto3自动获取凭证,兼容EC2实例的IMDSv1、IMDSv2两种元数据模式,也不需要自行处理元数据请求异常,修改后的凭证获取逻辑如下:
def get_credentials(): # boto3会自动从EC2元数据、环境变量、配置文件等位置自动获取可用凭证 session = boto3.Session() return session.get_credentials().get_frozen_credentials() # 调用方式 credentials = get_credentials() auth = AWSRequestsAuth( aws_access_key=credentials.access_key, aws_secret_access_key=credentials.secret_key, aws_token=credentials.token, aws_host='你的API域名', aws_region='AWS区域编码', aws_service='execute-api' )
注意事项
- 你贴出的代码中
method、jsonInput、body、headers变量未做定义,需要自行补充对应赋值逻辑,避免后续出现未定义变量报错。 - 确保EC2绑定的IAM角色已经配置了对应AWS服务API的调用权限。
内容的提问来源于stack exchange,提问作者snowcoder
相关产品推荐
相关产品推荐

