我有一个AWS API网关,我想使用IAM角色来保护它。
我正在寻找一个包来帮助我使用Python访问它。我试图避免实现整个版本4签名过程。我相信一定有什么图书馆可以用。
我研究了一下aws-requests-auth,但是它需要一个"aws_service"来生成签名。我也看了boto3,但我无法找到任何方法来添加身份验证头到一般请求。
您可以使用aws-requests-auth以execute-api作为服务名为您对API Gateway的请求生成签名。
import requests
from aws_requests_auth.aws_auth import AWSRequestsAuth
auth = AWSRequestsAuth(aws_access_key='YOURKEY',
aws_secret_access_key='YOURSECRET',
aws_host='restapiid.execute-api.us-east-1.amazonaws.com',
aws_region='us-east-1',
aws_service='execute-api')
headers = {'params': 'ABC'}
response = requests.get('https://restapiid.execute-api.us-east-1.amazonaws.com/stage/resource_path',
auth=auth, headers=headers)
基于Ka Hou Ieong的回应,还有一件事让我困惑。我使用aws-requests-auth==0.3.0
,在使用requests.get(url, auth=auth)
时,我仍然得到403
。
;TLDR;:我的URL有一个querystring,看起来aws-requests-auth
没有或可能无法确保querystring参数按升序排序和%
编码。
==>因此,一旦我将url
查询字符串更改为有序和%
编码,我得到200
。
:我打开了API网关日志记录,我得到了
In [46]: resp = requests.get(url, auth=auth)
In [47]: resp.text
Out[47]: u'{"message":"The request signature we calculated
does not match the signature you provided. Check your AWS Secret Access Key
and signing method. Consult the service documentation for details....
(上面的新行和截断(...
)是我的)
根据Amazon规范请求签名版本4文档,
要构造规范查询字符串,请完成以下步骤:
按字符码位升序排列参数名。例如,以大写字母F开头的参数名位于以小写字母b开头的参数名之前。
按照以下规则对每个参数名和值进行uri编码:
。不要对RFC 3986定义的任何无保留字符进行uri编码:A-Z, A-Z, 0-9,连字符(-),下划线(_),句点(.),和波浪(~)。
b。用%XY对所有其他字符进行百分比编码,其中X和Y是十六进制字符(0-9和大写字母A-F)。例如,空格字符必须编码为%20(不像某些编码方案那样使用'+'),扩展的UTF-8字符必须以%XY%ZA%BC的形式。
该正则 querystring用于生成Authorization Signature
, AWS在计算Signature Version 4
签名时应用相同的规则。底线,我认为aws-requests-auth
Auth
当然不能改变你的url
,你必须。
如果您想使用IAM角色进行呼叫,您应该使用BotoAWSRequestsAuth
from aw -requests-auth:
import requests
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
auth = BotoAWSRequestsAuth(
aws_host="API_ID.execute-api.us-east-1.amazonaws.com",
aws_region="us-east-1",
aws_service="execute-api"
)
response = requests.get("https://API_ID.execute-api.us-east-1.amazonaws.com/STAGE/RESOURCE", auth=auth)
这将使用botocore从AWS元数据服务检索密钥和秘密,而不需要您自己传递它们。
感谢Ka Hou Leong提供的laws -requests-auth库的建议。
另一个决定是使用requests_aws4auth包:
import requests
from requests_aws4auth import AWS4Auth
session = requests.Session()
session.auth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, 'us-east-1', 'execute-api')
response = requests.get('https://restapiid.execute-api.us-east-1.amazonaws.com/stage/resource_path', auth=auth)
同样,你需要为你的IAM用户添加执行权限,就像这些(区域内的所有API端点都可以被调用):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"arn:aws:execute-api:us-east-1:*:*"
]
}
]
}
链接