簡體   English   中英

從 Python 訪問具有 IAM 角色的 AWS API Gateway

[英]Access AWS API Gateway with IAM roles from Python

我有一個 AWS API 網關,我想使用IAM 角色來保護它。

我正在尋找一個包來幫助我使用 Python 訪問它。 我試圖避免實施整個第 4 版簽名流程 我相信一定有一些我可以使用的庫。

我查看了aws-requests-auth但它需要一個“aws_service”來生成簽名。 我也看過 boto3,但我找不到任何方法來將身份驗證標頭添加到一般請求。

您可以使用aws-requests-auth為您對 API Gateway 的請求生成簽名,並將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)

只是為了建立在Ka Hou Ieong的回應之上,還有一件事讓我絆倒了。 我正在使用aws-requests-auth==0.3.0 ,並且在使用requests.get(url, auth=auth)我仍然得到403

;TLDR; :我的URL有一個查詢字符串,看起來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.... 

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

根據Amazon Canonical Request for Signature Version 4文檔,

要構造規范查詢字符串,請完成以下步驟:

按字符代碼點升序對參數名稱進行排序。 例如,以大寫字母 F 開頭的參數名稱位於以小寫字母 b 開頭的參數名稱之前。

根據以下規則對每個參數名稱和值進行 URI 編碼:

a. 不要對 RFC 3986 定義的任何非保留字符進行 URI 編碼:AZ、az、0-9、連字符 (-)、下划線 (_)、句點 (.) 和波浪號 (~)。

使用 %XY 對所有其他字符進行百分比編碼,其中 X 和 Y 是十六進制字符(0-9 和大寫 AF)。 例如,空格字符必須編碼為 %20(不像某些編碼方案那樣使用“+”),並且擴展的 UTF-8 字符必須采用 %XY%ZA%BC 的形式。

規范查詢字符串用於生成Authorization Signature ,AWS 在計算Signature Version 4 sig 時應用相同的規則。 最重要的是,我認為當然aws-requests-auth Auth當然不能更改您的url ,您必須這樣做。

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

可以通過鏈接找到更多權限示例

如果您想使用 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 庫的建議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM