借助AWS Boto3从EC2实例调用API Gateway遇鉴权问题求助
解决EC2实例调用API Gateway时的"Authentication missing"错误
我看了你遇到的问题,核心原因是直接把boto3的credentials对象传给requests的auth参数是行不通的——requests无法识别这种格式的认证信息,而API Gateway的IAM授权要求请求必须通过AWS签名版本4(SigV4)来签名,这时候AWSRequestsAuth才是正确的工具。
下面是修正后的完整代码,我会一步步拆解关键点:
import boto3 import requests from aws_requests_auth.aws_auth import AWSRequestsAuth # 获取EC2实例角色的临时凭证(包含必要的token) session = boto3.Session() credentials = session.get_credentials() current_creds = credentials.get_frozen_credentials() # 构建SigV4签名认证对象,这是请求通过IAM授权的核心 auth = AWSRequestsAuth( aws_access_key=current_creds.access_key, aws_secret_access_key=current_creds.secret_key, aws_token=current_creds.token, # EC2角色的临时凭证必须携带token,不可省略 aws_host="restapiid.execute-api.us-east-1.amazonaws.com", aws_region="us-east-1", aws_service="execute-api" ) # 整理请求参数:查询参数用requests的params传递,而非headers request_params = {'params': 'ABC'} # 按需设置请求头,比如指定内容类型 request_headers = {'Content-Type': 'application/json'} # 发送请求,传入构建好的auth对象 response = requests.get( 'https://restapiid.execute-api.us-east-1.amazonaws.com/stage/resource_path', auth=auth, params=request_params, headers=request_headers ) # 打印响应信息用于排查 print(f"状态码: {response.status_code}") print(f"响应内容: {response.text}")
关键注意事项
- 凭证传递细节:必须用
get_frozen_credentials()获取包含临时token的完整凭证,EC2实例的IAM角色凭证是临时生成的,token是签名的必要组成部分,漏掉会直接导致认证失败。 - AWSRequestsAuth参数准确性:
aws_host要填写API Gateway的完整域名(不要带https://前缀),aws_service固定为execute-api,区域要和你的API部署区域完全一致。 - 参数位置修正:不要把URL查询参数放在headers里,requests的
params参数才是专门用于传递查询参数的,headers仅存放请求头相关信息。
额外排查点
- IAM角色权限验证:确保EC2实例的IAM角色拥有调用目标API的权限,可添加如下示例政策:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:us-east-1:你的AWS账号ID:restapiid/stage/GET/resource_path" } ] } - API Gateway授权配置:确认目标API方法的授权类型已设置为
AWS_IAM(可在API Gateway控制台的「方法请求」设置中修改)。 - 实例角色有效性:在EC2实例上执行
aws sts get-caller-identity命令,验证实例是否能正确获取IAM角色身份,排除角色关联失败的问题。
内容的提问来源于stack exchange,提问作者snowcoder
相关产品推荐
相关产品推荐

