使用Python

时间:2016-09-06 15:22:27

标签: python amazon-iam aws-api-gateway

我想要使用IAM Roles保护AWS API网关。

我正在寻找一个帮助我使用Python访问它的软件包。我试图避免实现整个Version 4 Signing Process。我确信必须有一些我可以使用的库。

我调查了aws-requests-auth,但它需要一个" aws_service"生成签名。我也查看了boto3,但我无法找到任何方法只将身份验证标头添加到一般请求中。

4 个答案:

答案 0 :(得分:14)

您可以使用aws-requests-auth为您的API网关请求生成签名,并使用 execute-api 作为服务名称。

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)

答案 1 :(得分:2)

为了建立在 Ka Hou Ieong 的回应之上,还有另一件事让我感到震惊。我使用的是aws-requests-auth==0.3.0,在使用requests.get(url, auth=auth)时,我仍然得到了403

; TLDR; :我的网址查询字符串,看起来aws-requests-auth没有或者可能不会确保查询字符串参数按升序排序% - 编码。

==> 因此,一旦我将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.... 

(上面的新行和截断(...)是我的)

根据亚马逊Canonical Request for Signature Version 4 文档,

  

要构建规范查询字符串,请完成以下步骤:

     

按字符代码点按升序对参数名称进行排序。例如,以大写字母F开头的参数名称位于以小写字母b开头的参数名称之前。

     

根据以下规则对每个参数名称和值进行URI编码:

     

a。不要对RFC 3986定义的任何非保留字符进行URI编码:AZ,az,0-9,连字符( - ),下划线(_),句点(。),和波浪号(〜)。

     

b。使用%XY对所有其他字符进行百分比编码,其中X和Y是十六进制字符(0-9和大写A-F)。例如,空格字符必须编码为%20(不使用&#39; +&#39;,如某些编码方案那样),扩展的UTF-8字符必须采用%XY%ZA%BC格式。< / p>

规范查询字符串用于生成Authorization Signature,AWS在计算Signature Version 4 sig时应用相同的规则。 最重要的是,我认为当然aws-requests-auth Auth当然不能改变你的url,你必须这样做。

答案 2 :(得分:1)

如果要使用IAM角色进行呼叫,则应使用aws-requests-auth中的BotoAWSRequestsAuth

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对aws-requests-auth库的建议。

答案 3 :(得分:1)

另一个决定是使用 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:*:*"
      ]
    }
  ]
}

可以通过link

找到更多权限示例