API Gateway でクロスアカウントの Lambda オーソライザーを設定してみた

AWS 公式ドキュメントのチュートリアルを参考にやってみました。
2022.08.02

こんにちは。アノテーションの中村(誠)です。
今回は以下の AWS 公式ドキュメントを参考に、API Gateway でクロスアカウントの Lambda オーソライザーを設定してみました。

Lambda コンソールで API Gateway Lambda オーソライザー関数を作成する

まずは、API Gateway Lambda オーソライザーを使用するの AWS 公式ドキュメントを参考に、Lambda オーソライザー関数を作成します。

1.Lambda コンソールで、「関数の作成」をクリックします。

2.「一から作成」を選択します。

3.関数の名前を入力します。

4.「関数の作成」をクリックします。

5.以下のコードをコピーしてコードエディタに貼り付けます。

// A simple token-based authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
// string, the authorizer function returns an HTTP 401 status code. For any other token value, 
// the authorizer returns an HTTP 500 status code. 
// Note that token values are case-sensitive.

exports.handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); // Return a 500 Invalid token response
    }
};

// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    var authResponse = {};
    
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; 
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; 
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}

6.「Deploy」をクリックします。

以上で Lambda オーソライザー関数の作成は完了です。
後述の手順で、作成した Lambda オーソライザー関数の ARN が必要なので、コピーしておきます。

API を作成する

API の作成についても、チュートリアル: サンプルをインポートして REST API を作成するを参考に実施します。
ただし、Lambda オーソライザー関数を作成した AWS アカウントとは別の AWS アカウントで実施します。

1.API Gateway コンソールから、「API を作成」をクリックします。

2.REST API で、「構築」をクリックします。

3.「API の例」を選択します。

4.「インポート」をクリックします。

API はこれで作成完了です。

クロスアカウントの Lambda オーソライザーを設定する

それでは、クロスアカウントの Lambda オーソライザーを設定するを参考に、本題のクロスアカウントの Lambda オーソライザーを設定します。

1.「オーソライザー」をクリックします。

2.「新しいオーソライザーの作成」をクリックします。

3.「オーソライザーの作成」の名前に、オーソライザー名を入力します。

4.タイプで「Lambda」選択します。

5.Lambda 関数は、先述の手順で作成した Lambda オーソライザー関数の ARN を貼り付けます。

6.Lambda 呼び出しロールは空白のままにします。

7.Lambda イベントペイロードで「トークン」 を選択します。

8.トークンのソースに「authorizationToken」と入力します。

9.「作成」をクリックします。

10.「Lambda 関数に権限を追加する」のダイアログが表示されるので、AWS CLI コマンドをコピーして、「そのまま作成」をクリックします。

11.オーソライザー ID をコピーします。

12.Lambda オーソライザー関数を作成した AWS アカウントに移動し、CloudShell を開きます。

13.10 でコピーした AWS CLI コマンドのうち、AUTHORIZER_ID を 11 でコピーしたオーソライザー ID に書き換えます。

aws lambda add-permission \
--function-name "arn:aws:lambda:ap-northeast-1:{Account-ID}:function:Lambda-Authorizer" \
--source-arn "arn:aws:execute-api:ap-northeast-1:{Account-ID}:ur06pvg2i1/authorizers/lptj0t" \
--principal apigateway.amazonaws.com \
--statement-id 1d1a2264-b592-4a77-874c-2cf8307f3dae \
--action lambda:InvokeFunction

14.AWS CLI コマンドを実行します。

15.API Gateway を作成した AWS アカウントに移動し、オーソライザーの「テスト」をクリックします。

16.authorizationToken の値に allow を入力し、「テスト」をクリックします。

17.成功すると、Response Code(応答コード): 200 とポリシーが返されます。

これでクロスアカウントの Lambda オーソライザーを設定できました。

API メソッドに Lambda オーソライザーを設定してみる

せっかくなので、API メソッドに Lambda オーソライザーを設定して、挙動を確認してみます。

GET メソッドのメソッドリクエストを開き、認可に作成済みの Lambda オーソライザーを設定します。

API をデプロイします。

デプロイ後に /pets の GET メソッドに、Postman からリクエストを送信してみます。

まずは、ヘッダーに何も付与せずに素のリクエストを送信してみると、Unauthorized が返ってきました。

続いて、ヘッダーのキーに authorizationToken 、値に allow を設定してリクエストを送信すると、バックエンドから結果が返ってきました。

クロスアカウントの Lambda オーソライザーが機能していることも確認できました。

API Gateway でクロスアカウントの Lambda を呼び出す方法について

Lambda オーソライザーではなく、クロスアカウントで通常の Lambda 関数を呼び出す方法については、以下の弊社ブログをご覧ください。

まとめ

今回は AWS 公式ドキュメントを参考に、API Gateway でクロスアカウントの Lambda オーソライザーを設定してみました。
基本的な手順は通常のクロスアカウントでの Lambda を呼び出す方法と同様ですが、AWS CLI コマンド実行時に、AUTHORIZER_ID をオーソライザー ID に書き換える必要がある点には注意が必要です。

今回の内容が参考になれば幸いです。

参考資料

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社 WEB サイトをご覧ください。