Lambda + CloudFront + S3でBasic認証する


やりたいこと

  • S3に配置したHTMLファイルを表示する前にBasic認証
    • ユーザがCloudFrontへアクセスしたらBasic認証される

構成

手順概要

  1. S3作成
    1-1. バケット作成
    1-2. Webサイトホスティング有効
  2. CloudFront作成
  3. Lambda作成
    3-1. Lambda用Role作成
    3-2. 関数作成
    3-3. バージョニング設定
    3-4. トリガー設定

手順

1.S3作成

1-1. バケット作成

バケット名を入力し次へ

何もせず次へ

何もせず次へ(パブリックアクセスは推奨値直か念のため確認)

バケットを作成

1-2. Webサイトホスティング有効

作成したバケットを作成

プロパティタブ内のStatic website hostingを選択

チェックを入れて有効化しindex.htmlを入力後保存する

2.CloudFront作成

Webタイプを選択する

下記情報を入力する

  • Origin Domain Name:作成したS3を選択
  • Restrict Bucket Access:Yes(S3へのアクセスをCloudFront経由のみに制限する)
  • Origin Access Identity:Create a New Identity(アクセスポリシーを作成する)
  • Grant Read Permissions on Bucket:Yes, Update Bucket Policy(S3のポリシーを自動アップデートする)

    下記情報を入力

  • Viewer Protocol Policy:Redirect HTTP to HTTPS(HTTPできたらHTTPSへリダイレクトする)

index.htmlを入力する

3.Lambda作成

3-1. Lambda用Role作成

ロールの作成

Lambda用のRoleにする

ポリシーを作成する

JSONタブを選択し下記ポリシーを入力する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:GetFunction",
                "lambda:EnableReplication*",
                "iam:CreateServiceLinkedRole",
                "cloudfront:CreateDistribution",
                "cloudfront:UpdateDistribution"
            ],
            "Resource": "*"
        }
    ]
}

ポリシー名を入力し作成完了

Role作成画面へ戻り作成したポリシーを選択する

Role名を入力し作成完了

作成したRoleを選択する

信頼関係を編集する

edgelambdaを追加する

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "edgelambda.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

信頼関係が追加されたことを確認する

3-2. 関数作成

Lambd画面で関数を作成する

一から作成し名前と作成したRoleを選択し関数の作成を押下する

index.jsに下記を入力し保存をする

'use strict';
exports.handler = (event, context, callback) => {

    // Get request and request headers
    const request = event.Records[0].cf.request;
    const headers = request.headers;
    console.log('request: ' + JSON.stringify(request));
    // Configure authentication
    const authUser = 'Takahashi';
    const authPass = 'Password';

    // Construct the Basic Auth string
    const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');

    // Require Basic authentication
    if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
        const body = 'Unauthorized';
        const response = {
            status: '401',
            statusDescription: 'Unauthorized',
            body: body,
            headers: {
                'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
            },
        };
        callback(null, response);
    }

    // Continue request processing if authentication passed
    callback(null, request);
};

3-3. バージョン作成

アクションから新しいバージョンを発行する

発行する(空欄でもOK)

3-4. トリガー設定

発行したバージョン内で左側のサービス一覧からCloudFrontを選択する

ディストリビューションに作成したCloudFrontのIDを入力後ビューアーリクエストを選択し追加する

4. 動作確認

CloudFrontにアクセスして認証されるか確認する。