本記事の概要
API GatewayのIAM認可の呼び出しをGETリクエストで行う記事はたくさんあるが、POSTリクエストで行う記事が見つからず苦労したので備忘
コード
main.py
import json
import boto3
import botocore.auth
import botocore.awsrequest
from botocore.endpoint import create_request_object
from botocore.httpsession import URLLib3Session
session = boto3.Session(profile_name='CLI_profile_name')
def sign_request(endpoint, method, data, service, region):
credentials = session.get_credentials()
auth = botocore.auth.SigV4Auth(credentials, service, region)
request = create_request_object({
'method': method,
'url': endpoint,
'body': data if method == 'POST' else '',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded' if method == 'POST' else 'application/json'
},
'params': {},
'context': {}
})
#prepared_request = botocore.awsrequest.AWSPreparedRequest(request)
auth.add_auth(request)
return request
def call_iam_protected_api(host, path, body, method='POST', region=None):
req = sign_request(
f'https://{host}{path}'
,method
,json.dumps(body).encode('utf-8')
,'execute-api'
,session.region_name if region is None else region
)
responseBody, statusCode = send_request(req)
return responseBody
def send_request(prepared_request):
session = URLLib3Session()
response = session.send(prepared_request.prepare())
return response.text, response.status_code
サンプルコード
main.py
r = call_iam_protected_api('******.execute-api.ap-northeast-1.amazonaws.com', '/path', '{"message": "hello"}', method='POST', region='ap-northeast-1')
print(r)
main.py
r = call_iam_protected_api('******.execute-api.ap-northeast-1.amazonaws.com', '/path', '', method='GET', region='ap-northeast-1')
print(r)
API Gateway側の設定
おまけ(Organization内からのアクセスを許可)
リソースポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:accountId***:api_id***/*",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-********"
}
}
}
]
}