Lambda + CloudFront + S3でBasic認証する

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


#構成
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/168635/246c19d6-04d3-83bd-0e46-5f25d9bbc8f6.png)


#手順概要
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. バケット作成
**バケット名を入力し次へ**
![WS000021.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/eb4529d4-3b06-5a7b-7a31-d5160764ab9c.jpeg)
**何もせず次へ**
![WS000022.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/114bc71b-5a9e-b0a6-2f7b-06eef27adc27.jpeg)
**何もせず次へ(パブリックアクセスは推奨値直か念のため確認)**
![WS000023.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/ef714854-4695-fa15-f94b-88361c087caa.jpeg)
**バケットを作成**
![WS000024.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/fb069dfa-e380-00ac-a56b-e6b63cebd845.jpeg)


###1-2. Webサイトホスティング有効
**作成したバケットを作成**
![WS000025.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/ddf0b243-bd90-67ee-d39c-7108599a274f.jpeg)
**プロパティタブ内のStatic website hostingを選択**
![WS000026.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/e3845a7a-2860-55ef-8888-cb3e07697df4.jpeg)
**チェックを入れて有効化しindex.htmlを入力後保存する**
![WS000027.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/448e1b63-b5eb-9b9d-54f9-ccd72259a835.jpeg)


##2.CloudFront作成
**Webタイプを選択する**
![WS000028.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/a88673f9-114a-aaca-b7f5-698229b8c923.jpeg)

**下記情報を入力する**

- 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のポリシーを自動アップデートする)
![WS000029.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/8366651c-4470-97b7-fee1-4d53050e3098.jpeg)
**下記情報を入力**

- Viewer Protocol Policy：Redirect HTTP to HTTPS(HTTPできたらHTTPSへリダイレクトする)
![WS000030.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/0a4bd5b2-2e6a-8228-25d5-2e2e9775a1b1.jpeg)

**index.htmlを入力する**
![WS000031.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/2b1eb5cd-a752-8fa1-fd1a-d7f383ab543b.jpeg)



##3.Lambda作成
###3-1. Lambda用Role作成
**ロールの作成**
![WS000032.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/26f25277-7340-d4b0-8d94-083cc7602f8d.jpeg)
**Lambda用のRoleにする**
![WS000033.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/b1022ea5-53bd-6491-709d-b886702217f3.jpeg)
**ポリシーを作成する**
![WS000034.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/3d19478c-9e6e-6cc5-c029-a9f53974b5b8.jpeg)
**JSONタブを選択し下記ポリシーを入力する**
![WS000035.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/fc9417f6-3f97-21e7-be44-a33d09b1d7d4.jpeg)

```
{
    "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": "*"
        }
    ]
}
```

**ポリシー名を入力し作成完了**
![WS000036.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/c72cfb8c-c288-7056-f857-bf7ea7b08a43.jpeg)
**Role作成画面へ戻り作成したポリシーを選択する**
![WS000037.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/539bfea7-b5b2-7f30-6132-beab764503a7.jpeg)
**Role名を入力し作成完了**
![WS000038.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/337b1998-57cf-7da5-75af-0a626f02d131.jpeg)
**作成したRoleを選択する**
![WS000039.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/4863cf7b-f287-db82-3acb-2e1df35647e1.jpeg)
**信頼関係を編集する**
![WS000040.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/dd07c7da-98cb-7685-ec58-2c6ddde14552.jpeg)
**edgelambdaを追加する**
![WS000041.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/2b0a20ab-8061-1551-0ee5-1f7238ceaedc.jpeg)

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

**信頼関係が追加されたことを確認する**
![WS000042.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/2dd9bf73-f50e-55ca-1111-31065ed59f10.jpeg)


###3-2. 関数作成
**Lambd画面で関数を作成する**
![WS000043.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/438d1216-b34f-b5a8-8dfd-50afddbc1f44.jpeg)
**一から作成し名前と作成したRoleを選択し関数の作成を押下する**
![WS000044.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/378170c7-066c-1b86-7e75-f69f6c034632.jpeg)
**index.jsに下記を入力し保存をする**
![WS000045.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/9c68e9ac-f669-ee72-12b8-dc4222c5c04f.jpeg)

```
'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. バージョン作成
**アクションから新しいバージョンを発行する**
![WS000046.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/7d20f3cf-b77f-1b1f-e732-31019fb8cdd6.jpeg)
**発行する(空欄でもOK)**
![WS000047.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/529937ee-f1d2-9cec-31ae-e1cecd39d5fa.jpeg)


###3-4. トリガー設定
**発行したバージョン内で左側のサービス一覧からCloudFrontを選択する**
![WS000048.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/f7ff0e4a-60c6-2d91-9331-c24ff7f2e867.jpeg)
**ディストリビューションに作成したCloudFrontのIDを入力後ビューアーリクエストを選択し追加する**
![WS000049.JPG](https://qiita-image-store.s3.amazonaws.com/0/168635/f8556903-b366-2558-c87d-991e2b29a771.jpeg)


##4. 動作確認
CloudFrontにアクセスして認証されるか確認する。