IAM認証を用いたAPIを構築する

こんにちはSCSK齋藤です。

今回は Amazon API Gateway の認証方法として、IAMを用いる方法を解説したいと思います。

 

概要

アーキテクチャ図は下に示す通りです。今回はAPI Gatewayの裏にLambdaを設けて、API呼び出しでLambdaが動くようにします。

なお、IAM認証の処理の流れは下記の通りとなります。

①APIの呼び出し元がAPIの呼び出しを行う。

②APIの呼び出し元に付与されているIAM Roleに対象API Gatewayを呼び出す権限があれば、APIを呼び出すことができる。

 

 

各リソースの作成

アーキテクチャ図を実現する、各リソースの作成をマネジメントコンソールベースで説明します。

Lambda

今回のAPI Gatewayの裏側にあるLambdaは、特に凝ったものにする必要がないので、デフォルトのソースコードそのままとします。

単純にステータスコード200と「Hello from Lambda!」と出力されるだけのシンプルなプログラムです。

 

API Gateway

最初は通常通りの作成を行います。

 

メソッドの作成も行います。今回は呼び出しができれば良いのでGetにし、先ほど作成したLambda関数を設定します。

作成後、認証設定を付与します。

まず、メソッドリクエストの編集ボタンを押下します。

 

認可の部分で、AWS IAMをクリックして、保存します。

APIの画面に戻るので、画面右上の「APIのデプロイ」をクリックします。

下記のような設定とし、デプロイをクリックします。

 

これにてAPI側の構築は完了です。

続いて、APIを呼び出す側のリソースを作成していきます。

今回は、呼び出し元はLambda関数を使いたいと思います。また、それに付与するIAM Roleも作成したいと思います。

 

Lambda(APIを呼び出す側)

今回は下記名前のLambdaを作成しました。Lambda関数の作成方法は、前述したものを同じなので省略します。

ここではソースコードを紹介します。

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

def lambda_handler(event, context):
    api_url = "https://XXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev"

    #①Lambdaに付与されたIAMロールをもとに、クレデンシャル情報を取得。
    lambda_credentials = boto3.Session().get_credentials()
    credentials = Credentials(lambda_credentials.access_key, lambda_credentials.secret_key, token=lambda_credentials.token)
    
    #②安全にアクセスするために、AWS Signature Version 4に基づいたヘッダー情報を生成する。
    request = AWSRequest(method="GET", url=api_url)
    SigV4Auth(credentials, "execute-api", "ap-northeast-1").add_auth(request)
    headers = {
        "Authorization": request.headers["Authorization"],
        "X-Amz-Date":request.context["timestamp"],
        "X-Amz-Security-Token": lambda_credentials.token
    }

    #③ヘッダー情報を付加してAPIへアクセスする。
    api_response = requests.get(api_url, headers=headers)

    api_response_json=api_response.json()
    
    print(f'api_response is {api_response_json}')


 

ソースコードの中にコメントアウトしておりますが、流れを解説すると3点に分けられます。

①Lambdaに付与されたIAMロールをもとに、クレデンシャル情報を取得。

boto3のライブラリを用いて、Lambdaのクレデンシャル情報を取得する処理を行います。

 

②安全にアクセスするために、AWS Signature Version 4に基づいたヘッダー情報を生成する。

AWSへのアクセスへは安全である必要があります。

今回はSigV4Authというライブラリを用いて、先ほど取得したクレデンシャルをベースにヘッダー情報を生成します。

 

③ヘッダー情報を付加してAPIへアクセスする。

ヘッダー情報を付加し、アクセスしたいAPIのURLへアクセスを行います。

 

IAM Role

呼び出し側LambdaのIAM Roleを編集し、APIGatewayを呼び出すための権限を付与します。

Lambdaの「設定」→「アクセス権限」からロール名をクリックします。

遷移したら、IAMRoleの画面が出るので、「アクセス許可を追加」→「インラインポリシーを作成」をクリックします。

ポリシーエディタで下記の条件で作成しました。

JSON形式にすると下記の通りです。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": "execute-api:Invoke",
			"Resource": "*"
		}
	]
}

 

挙動確認

これまでで準備は完了となります。

では、実際にLambdaのテストとして動作確認をしてみますと、ログ出力のところでAPIの裏側のLambdaとして実装したステータスコード200と「Hello from Lambda!」が出力されていることがわかります。

まとめ

今回はAPI GatewayのIAM認証を呼び出す方法について記載いたしました。

なお、補足ですが今回呼び出し側のLambdaにて、ライブラリにSigV4Authというものを利用しました。

これとは別にAWS4Authというライブラリもあり、こちらを使ってもアクセスは可能となります。

しかし、AWS4Authは2024年7月22日を最後にメンテナンスがされておらず、Python3.13以降には対応しておりません。

requests-aws4auth
AWS4 authentication for Requests

 

SigV4Authは、botocoreに内包されているため、Python3.13以降にも対応しております。そのため、今後のことを考えるとSigV4Authを利用することを推奨いたします。

botocore
Low-level, data-driven core of boto 3.
著者について

フロントエンドもバックエンドも両方少しずつ勉強して、フルスタックエンジニアを目指してます。
サーバレス開発の楽しさを実感中!

ANGEL Dojo 2021 ANGEL賞、ベストアーキテクチャ賞ダブル受賞
2023 Japan AWS Jr. Champions
2022〜24 Japan AWS All Certifications Engineers

齋藤友宏をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(AWS)は、企業価値の向上につながるAWS 導入を全面支援するオールインワンサービスです。AWS最上位パートナーとして、多種多様な業界のシステム構築実績を持つSCSKが、お客様のDX推進を強力にサポートします。

AWSアプリケーション開発クラウドソリューション
シェアする
タイトルとURLをコピーしました