AWS API GatewayのIAM認証をSigV4署名(Python)で作成


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

はじめに

API Gatewayを利用していましたが、あまりにインターネットに対して無防備だったのでIAM認証を実装することにしました。
検証ではPostmanを利用して確認していましたが、対象とするインターネット経由でのユーザに導入してもらえるわけでもないので、PythonでSigV4署名を作成してみたいと思います。

参考:API GatewayでAPIにIAM認証をかけて、Node.jsでSigV4署名ヘッダを作成してリクエストしてみる

IAM認証とは?

AWS Identity and Access Management (IAM) は、AWS リソースへのアクセスを管理するためのサービスです。管理する中には、認証(サインイン)の制御も含まれます。

その認証(サインイン)の一つに、『IAMのアクセスキー(アクセスキーID+シークレットアクセスキー)とハッシュ関数を使い、AWSへHTTPリクエストに認証情報を追加するという技術(SigV4署名)』を利用した制御のIAM認証というものがあります。

参考:IAM 認証の使用
参考:署名バージョン 4 の署名プロセス

構成イメージ

・前提条件:APIGateway+Lambdaを実装している
参照:AWS Lambdaを利用したLINEbotハンズオン -3・4の構築部分参照-

・API GatewayにIAM認証を付与し、CLIからAPI Gatewayのエンドポイントを叩いて、後続のLambdaが動くという流れ

ハンズオン

0.前提としてのAWS環境の確認

0.1 APIGatewayにIAM認証が設定されている

「API Gateway」の「リソース」で「認可」が「AWS IAM」と設定している

0.2 APIGatewayとLambdaが紐づいている

0.3 Lambdaでの画面の状態

Lambdaの「トリガー」に「API Gateway」が設定されている

1.SigV4署名(Python)のコード

SigV4署名コード詳細

import os
from botocore.awsrequest import AWSRequest
from botocore.auth import SigV4Auth
from botocore.endpoint import URLLib3Session
from botocore.credentials import Credentials
import requests

### 1.APIエンドポイントURL
url_ = "https://{restapi_id }.execute-api.{region}.amazonaws.com/{stage_name}/test-lambda-inamura"

### 2. Credential生成
credentials = Credentials(os.getenv['AWS_ACCESS_KEY_ID'], os.getenv['AWS_SECRET_ACCESS_KEY'])

### 3. AWSRequest生成
request = AWSRequest(method="GET", url=url_)

### 4. AWSリクエスト署名
SigV4Auth(credentials, 'execute-api', "ap-northeast-1").add_auth(request)

### 5. API発行
headers = {
    'Authorization': request.headers['Authorization'],
    'Host':'kzetkt1i30.execute-api.ap-northeast-1.amazonaws.com',
    'X-Amz-Date':request.context['timestamp']
}

### 6.リクエスト・レスポンスの内容
response = requests.get(url_,headers=headers)

print(response.text)

挙動の確認

ターミナル画面で実行した画面

tetutetu214@mbp hanson % python check_iam.py

"Hello from Lambda!"

IAM認証なしで、直接REST APIエンドポイントにアクセスしてみた画面

トークンがないことでアクセスを拒否されています

tetutetu214@mbp hanson % curl https://{restapi_id }.execute-api.{region}.amazonaws.com/{stage_name}/test-lambda-inamura

{"message":"Missing Authentication Token"}%

まとめ

意外とさっくりできましたが、なおさらPostmanの便利さに気がついたような気もします。
結果的には、Amazon API GatewayのAPIクライアントSDKを生成してからの呼び出しを利用するので、とりあえず確認程度の構築となりました。

参考資料

IAM認証のAWS API GatewayにPythonからSigV4署名してアクセスするには
完全な署名バージョン 4 署名プロセスの例 (Python)

Last modified: 2022-05-21

Author