CloudFrontとLambdaでBasic認証設定してみた

こんにちは
「あつまれどうぶつの森」のためにswitchの販売抽選に応募するが当たらず「あつもり」ブームも過ぎていたことに最近気付いたstreampackのrisakoです:girl_tone1::koala:
そして9月も後半！だんだん涼しくなってきて過ごしやすくなってきましたね！

今回のテーマは「Basic認証」です:dizzy:
これまでなかなか触れることがなかったので、初めて設定してみた記念にQiitaに残そうと思います。
#Basic認証とは？
Web上で利用できる認証システムのことです。
Basic認証が設定されているページにアクセスすると、ブラウザ上に**ユーザー名とパスワード**を入力するポップアップが表示されます。
私はBasic認証を意識する前に数回web上でみたことがあるので、多くの人が見たことがあるのではないでしょうか？

Safariだとこのようなポップアップが出てきます!
![スクリーンショット 2020-09-16 13.17.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429615/d2bf4ebc-93ab-8c2e-be97-3b62c91b860c.png)


#事前に用意するもの
- S3 bucketに保存したhtmlなど


Basic認証で保護したいwebページなどをS3bucketに保存しておきます。

#まず初めにCloudFront設定
デフォルトの設定から変更が必要な箇所のみ記載します。
###Origin Settings
- Origin Domain Name：webページで保存したS3bucketを指定します

###Default Cache Behavior Settings
- Viewer Protocol Policy ：Redirect HTTP to HTTPS
- Cache and origin request settings：Use legacy cache settings
- Cache Based on Selected Request Headers：Whitelist
- Whitelist Headers：Access-Control-Request-Headers・Access-Control-Request-Method・Origin
- Object Caching：全てのTTLを0にする

###Distribution Settings
- Default Root Object：S3に保存しているwebページをしていると、CloudFrontのURLから直で行けるので便利です。例えば、https://CF-URL/test.html と指定しなくてもhttps://CF-URL だけで、test.htmlが表示されます。


#次にLambda設定
:star: **Lambda@edgeを使用できるリージョンは米国東部（バージニア北部）のみなのでリージョンを移動します。**

- 任意の関数名を入力します。
- ランタイム：Node.js 12.x
- 実行ロール：Basic認証用に作成したものとわかるように命名します。仮に（test-basic-role）とします。
- ポリシーテンプレート：「基本的なLambda@Edgeのアクセス権限（CloudFrontトリガーの場合」を選択
![スクリーンショット 2020-09-24 15.35.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429615/e24b1279-1818-ec9d-d500-cc88442a3d05.png)

Lambda関数が作成できたら、コードを書いていきます :pen_ballpoint: 
[参考記事](https://dev.classmethod.jp/articles/directory-indexes-in-s3-origin-backed-cloudfront/)のコードを使わせてもらっています。
下記の箇所を自分の設定したいユーザー名とパスワードに変更してください。
ここで設定したユーザー名とパスワードがbasic認証で使用するものになります。


>    // Configure authentication
    const authUser = 'user';
    const authPass = 'pass';

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

    // Get request and request headers
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    // Configure authentication
    const authUser = 'user';
    const authPass = 'pass';

    // 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);
};

```

コードを保存したら、右上に表示される「アクション」から「Lambda@Edgeへのデプロイ」に進みます。
![スクリーンショット 2020-09-24 15.49.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429615/879054dd-b5ff-4281-d457-c472793171dc.png)

###CloudFront トリガーの設定

- 先ほど作成したCloudFrontを指定します。
- CloudFrontイベント：ビューアーリクエスト
- Lambda@Edge へのデプロイを確認：:heavy_check_mark:を入れます
- 「デプロイ」を押下

![スクリーンショット 2020-09-24 15.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429615/1e5a97e4-3a66-ac82-f4a3-42913851e1db.png)


##Cloudfrontとlambdaが連携できているか確認する

作成したCloudFrontの**Behavior**から確認します。
###Lambda Function Associations
- CloudFront Event：Viewer Request
- Lambda Function ARN：Lambda@EdgeのARN

![スクリーンショット 2020-09-24 16.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429615/d73bd03e-2489-9e1d-c897-586d24c92076.png)

#動作確認

CloudFrontのドメインでアクセスしてみましょう。
>https://xxxxxxx.cloudfront.net
![スクリーンショット 2020-09-24 16.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429615/1208ef43-e759-ed60-288e-0eedee682617.png)

Basic認証がちゃんと設定されているようです。
設定したユーザー名とパスワードでログインできればOKです！:ok_hand: 

#参考
[簡単だった！CloudFront + S3 に BASIC認証を入れる方法](https://kahoo.blog/howto-basic-auth-on-cloudfront-s3)
[できた！S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法](https://dev.classmethod.jp/articles/directory-indexes-in-s3-origin-backed-cloudfront/)