IAM 인증의 AWS API Gateway에 Python에서 SigV4 서명하고 액세스하려면
9165 단어 IAM파이썬APIGatewayAWS
API Gateway의 메소드 설정 화면은 이런 느낌입니다. 영어 매니지먼트 콘솔이라면 「Authorization」, 일본어라면 「인가」라는 란입니다.
기본값은 NONE으로 설정되어 있지만 AWS_IAM으로 설정하면 API Gateway는 도착한 요청의 서명을 확인합니다. 요청하는 사람이 서명해야 합니다.
API Gateway가 서명을 확인하게 되면 API Gateway의 리소스 정책에서 IAM 사용자 및 IAM 역할에 제한을 걸 수 있습니다.
Python에서 서명하고 API를 요청하는 샘플 코드를 작성합니다.
전제
IAM 사용자의 액세스 키가 ~/.aws/credentials
로 설정되어 있고 해당 IAM 사용자에서 IAM 역할로 전환하는 IAM 권한이 있고 해당 IAM 역할에서 API Gateway에 액세스한다고 가정합니다. (.
파이썬 코드
import boto3
from botocore.awsrequest import AWSRequest
from botocore.auth import SigV4Auth
import urllib.request
import sys
endpoint_host = "xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com"
endpoint = "https://" + endpoint_host + "/stage"
path = "/hello"
url = endpoint + path
# .aws/credentials または環境変数でアクセスキーが設定されているIAMユーザのセッションを生成。
session = boto3.session.Session()
# .aws/credentials に複数のIAMユーザがある場合は profile_name を指定。
#session = boto3.session.Session(profile_name = "foo")
sts_client = session.client("sts")
# IAMロールのARNを指定して assume_role 。
# IAMロールが不要でIAMユーザのままでAPIリクエストする場合は、ここは不要。
assume_role_response = sts_client.assume_role(
RoleArn = "arn:aws:iam::XXXXXXXXXXXX:role/ROLENAME",
RoleSessionName = "test")
# assume_role で得られたトークンなどからIAMロールでのセッションを生成。
# IAMロールが不要でIAMユーザのままでAPIリクエストする場合は、ここは不要。
session = boto3.session.Session(
aws_access_key_id = assume_role_response['Credentials']['AccessKeyId'],
aws_secret_access_key = assume_role_response['Credentials']['SecretAccessKey'],
aws_session_token = assume_role_response['Credentials']['SessionToken'])
# セッション情報からAPIリクエストに署名。
credentials = session.get_credentials()
awsreq = AWSRequest(method = "GET", url = url)
SigV4Auth(credentials, "execute-api", "ap-northeast-1").add_auth(awsreq)
# urllib.request.Request 生成。
# この4つのリクエストヘッダーが必須。
# IAMロールが不要でIAMユーザのままでAPIリクエストする場合は、X-Amz-Security-Token は不要。
req = urllib.request.Request(url, headers = {
"Authorization": awsreq.headers['Authorization'],
"Host": endpoint_host,
"X-Amz-Date": awsreq.context['timestamp'],
"X-Amz-Security-Token": assume_role_response["Credentials"]["SessionToken"]
})
# APIリクエスト実行
try:
with urllib.request.urlopen(req) as response:
# レスポンス出力
sys.stdout.buffer.write(response.read())
except urllib.error.HTTPError as err:
# 403などの場合はここに到達
# エラーを出力
print(err)
# レスポンスヘッダを出力
print(err.headers)
오류 메시지의 예
IAM 사용자에게 assume_role 할 권한이 없으면 assume_role을 호출하면
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation
예외가 발생합니다.
~/.aws/credentials
가 필요한데 부족하면, 403 Forbidden 가 돌려주어져 응답 헤더에 다음과 같이 쓰여집니다.
x-amzn-ErrorType: UnrecognizedClientException
API Gateway 리소스 정책에서 이 IAM 역할의 요청을 거부하면 403 Forbidden이 반환되고 응답 헤더에 다음과 같이 작성됩니다.
x-amzn-ErrorType: AccessDeniedException
IAM 역할에 API Gateway에 액세스하는 IAM 권한이 없어도 API Gateway 리소스 정책에서 허용하면 AccessDeniedException이 아닌 성공적으로 처리 할 수 있습니다.
링크
C#에서 기사도 썼습니다.
import boto3
from botocore.awsrequest import AWSRequest
from botocore.auth import SigV4Auth
import urllib.request
import sys
endpoint_host = "xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com"
endpoint = "https://" + endpoint_host + "/stage"
path = "/hello"
url = endpoint + path
# .aws/credentials または環境変数でアクセスキーが設定されているIAMユーザのセッションを生成。
session = boto3.session.Session()
# .aws/credentials に複数のIAMユーザがある場合は profile_name を指定。
#session = boto3.session.Session(profile_name = "foo")
sts_client = session.client("sts")
# IAMロールのARNを指定して assume_role 。
# IAMロールが不要でIAMユーザのままでAPIリクエストする場合は、ここは不要。
assume_role_response = sts_client.assume_role(
RoleArn = "arn:aws:iam::XXXXXXXXXXXX:role/ROLENAME",
RoleSessionName = "test")
# assume_role で得られたトークンなどからIAMロールでのセッションを生成。
# IAMロールが不要でIAMユーザのままでAPIリクエストする場合は、ここは不要。
session = boto3.session.Session(
aws_access_key_id = assume_role_response['Credentials']['AccessKeyId'],
aws_secret_access_key = assume_role_response['Credentials']['SecretAccessKey'],
aws_session_token = assume_role_response['Credentials']['SessionToken'])
# セッション情報からAPIリクエストに署名。
credentials = session.get_credentials()
awsreq = AWSRequest(method = "GET", url = url)
SigV4Auth(credentials, "execute-api", "ap-northeast-1").add_auth(awsreq)
# urllib.request.Request 生成。
# この4つのリクエストヘッダーが必須。
# IAMロールが不要でIAMユーザのままでAPIリクエストする場合は、X-Amz-Security-Token は不要。
req = urllib.request.Request(url, headers = {
"Authorization": awsreq.headers['Authorization'],
"Host": endpoint_host,
"X-Amz-Date": awsreq.context['timestamp'],
"X-Amz-Security-Token": assume_role_response["Credentials"]["SessionToken"]
})
# APIリクエスト実行
try:
with urllib.request.urlopen(req) as response:
# レスポンス出力
sys.stdout.buffer.write(response.read())
except urllib.error.HTTPError as err:
# 403などの場合はここに到達
# エラーを出力
print(err)
# レスポンスヘッダを出力
print(err.headers)
오류 메시지의 예
IAM 사용자에게 assume_role 할 권한이 없으면 assume_role을 호출하면
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation
예외가 발생합니다.
~/.aws/credentials
가 필요한데 부족하면, 403 Forbidden 가 돌려주어져 응답 헤더에 다음과 같이 쓰여집니다.
x-amzn-ErrorType: UnrecognizedClientException
API Gateway 리소스 정책에서 이 IAM 역할의 요청을 거부하면 403 Forbidden이 반환되고 응답 헤더에 다음과 같이 작성됩니다.
x-amzn-ErrorType: AccessDeniedException
IAM 역할에 API Gateway에 액세스하는 IAM 권한이 없어도 API Gateway 리소스 정책에서 허용하면 AccessDeniedException이 아닌 성공적으로 처리 할 수 있습니다.
링크
C#에서 기사도 썼습니다.
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation
x-amzn-ErrorType: UnrecognizedClientException
x-amzn-ErrorType: AccessDeniedException
C#에서 기사도 썼습니다.
Reference
이 문제에 관하여(IAM 인증의 AWS API Gateway에 Python에서 SigV4 서명하고 액세스하려면), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/suzuki-navi/items/1ea284c97075f3a34b30텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)