はじめに
タイトル通り、API GatewayでLambdaオーソライザーとAPIキーを同時に設定してみたので、そのまとめです。
Lambdaオーソライザーとは、
Lambda オーソライザー (以前のカスタムオーソライザー) は、Lambda 関数を使用して API へのアクセスを制御する API Gateway の機能です。
本稿では説明しませんので、詳しく知りたい方は公式ドキュメントを見てください。
今まで、API GatewayのAPIキーと、Lambdaオーソライザーをそれぞれ片方ずつ利用したことがあったのですが。今回、API実行数の制御を行いながら、認可をする必要があったため同時に利用することにしました。
Lambdaオーソライザー
package main
import (
"context"
"errors"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
// Help function to generate an IAM policy
func generatePolicy(principalId, effect, resource string) events.APIGatewayCustomAuthorizerResponse {
authResponse := events.APIGatewayCustomAuthorizerResponse{PrincipalID: principalId}
if effect != "" && resource != "" {
authResponse.PolicyDocument = events.APIGatewayCustomAuthorizerPolicy{
Version: "2012-10-17",
Statement: []events.IAMPolicyStatement{
{
Action: []string{"execute-api:Invoke"},
Effect: effect,
Resource: []string{resource},
},
},
}
}
return authResponse
}
func handleRequest(ctx context.Context, event events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
if cookie, ok := event.Headers["Cookie"]; ok {
// ここで認可処理をおこなう。例としてCookieを取得している
fmt.Print("cookie: " + cookie)
} else {
return events.APIGatewayCustomAuthorizerResponse{}, errors.New("Unauthorized")
}
return generatePolicy("user", "Allow", event.MethodArn), nil
}
func main() {
lambda.Start(handleRequest)
}
処理フロー
実際に動作させて確認した処理フローはこのようになりました。
処理される順序としては、Lambdaオーソライザー→APIキー認証ということになりました。
検証前の予想では、APIキー認証→Lambdaオーソライザーの順かなって思っていたので、ちょっと意外でした。
これは、APIキーは認証に使うものではなく顧客に**「リクエストレートとクォータ」を提供するためのキー**という位置づけだからだと思われます。
仮にオーソライザー(認可)で弾かれた場合は、APIキー認証まで到達しないため、APIGatewayの使用量プランで設定したクォータが無駄に消費されることはありません。(素晴らしい)
まとめ
- LambdaオーソライザーとAPIキー認証を同時に利用することはできます。
- 順序としては、Lambdaオーソライザーが呼ばれたあとに、認可OKの場合APIキー認証が実行されます。
- Lambdaオーソライザーで401 Unauthorizedを返却した場合はAPIキー認証にはいきません。
参考