Amazon API Gateway+AWS LambdaでHTTP Basic認証を実装したけれど失敗した

## この記事を3行で

2018年4月23日追記: 未確認ですが現在は`WWW-Authenticate`レスポンスヘッダ対応しているとの情報あり。コメント欄を参照のこと。

* ~~結論: 現時点(2016年3月24日)では、Amazon API Gatewayで***Webブラウザからの***HTTP Basic認証を行うことができない。（おそらく、HTTP Digest認証も同様）~~
* Amazon API Gatewayは`401 Authorization Required`ステータスのレスポンスを返すことができる。
* ~~Amazon API Gatewayは`WWW-Authenticate`レスポンスヘッダを返すことができない。（置換される）~~

## 2016年3月25日0時10分 追記

本記事に対して、[はてなブックマーク](http://b.hatena.ne.jp/entry/qiita.com/yuyakato/items/4b8d75c2d716b1d2244c)にて以下のコメントを頂きました。

> id:nekoruri
> これWWW-Authenticateを返さないからブラウザ等でBasic認証のダイアログを出せないだけで、Basic認証というかAuthorizationヘッダによる処理そのものはできるような気がする。

おっしゃる通りです。この記事は「WebブラウザからのBasic認証」について書いていたつもりでしたが、それについての記述が一切無かったため、一部修正しました。
コメントありがとうございます！

`Authorization`リクエストヘッダが問題無く通るかどうかについては、別途試してみたいと思います。

## 1. 概要

知人との雑談の中で「Amazon API Gatewayで[HTTP Basic認証](https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC)が使えたら便利だね」という話になったので、実現可能かどうか試してみました。
結果、***Webブラウザからは***HTTP Basic認証を行うことができませんでした。

## 2. 実験内容

試した内容を以下に示します。

### 2.1. Lambda関数を準備

Amazon API GatewayからWebブラウザに`401 Authorization Required`を返すために、必ず失敗するLambda関数を準備しました。

```index.js
exports.handler = function(event, context) {
    context.fail("AUTHORIZATION_REQUIRED");
};
```

### 2.2. APIとして公開

上記のLambda関数を、Amazon API Gatewayを使ってAPIとして公開しました。

#### 2.2.1. 概要

今回は`/qiita/auth/basic`というパスにGETメソッドを作成しました。概要は以下の通りです。

![overview.png](https://qiita-image-store.s3.amazonaws.com/0/58479/8904b76e-6d34-27a9-53c3-3d9a1ec696b4.png)


#### 2.2.2. Method Response

「Method Response」の設定は以下の通り。

1. 「Add Response」リンクをクリックする。
2. 「HTTP Status」として「401」を追加する。
3. 「Response Headers」として「WWW-Authenticate」を追加する。

![method_response.png](https://qiita-image-store.s3.amazonaws.com/0/58479/3fb63ff6-b92e-f479-551d-d02e6d459124.png)

#### 2.2.3. Integration Response

「Integration Response」の設定は以下の通り。

1. 「Add integration response」リンクをクリックする。
2. 「Lambda Error Regex」に「AUTHORIZATION_REQUIRED」を入力する。本来は正規表現が使えるはずだけれど、なぜか上手く行かなかったので完全一致で入力した。
3. 「Header Mappings」の「WWW-Authenticate」に「'Basic realm="SECRET AREA"'」を入力する。シングルクオートに注意。

![integration_response.png](https://qiita-image-store.s3.amazonaws.com/0/58479/6a961673-119e-9c12-ed1b-5623eee076ff.png)

### 2.3. curlで実験

`curl`コマンドでAPIを叩いてみると、`401 Unauthorized`が返ってきていますが`WWW-Authenticate`レスポンスヘッダが`x-amzn-Remapped-WWW-Authenticate`になっており、ヘッダ名が置換されています。
詳しくはわかりませんが、セキュリティ上の措置と思われます。

```
$ curl -v "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/qiita/auth/basic"
*   Trying 54.230.109.80...
* Connected to xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com (54.230.109.80) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.execute-api.ap-northeast-1.amazonaws.com
* Server certificate: Symantec Class 3 Secure Server CA - G4
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> GET /v1/qiita/auth/basic HTTP/1.1
> Host: xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Type: application/json
< Content-Length: 41
< Connection: keep-alive
< Date: Thu, 24 Mar 2016 07:20:12 GMT
< x-amzn-Remapped-WWW-Authenticate: Basic realm="SECRET AREA"
< x-amzn-RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
< X-Cache: Error from cloudfront
< Via: 1.1 d07ff9c45b4428f56e92ac1d86529e94.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: 1KXn1I6MfU0_5Hc4-CO24WZ_3c0uQ4WzyBB_FfeX5tSuOOwtMSgIrA==
<
* Connection #0 to host xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com left intact
{"errorMessage":"AUTHORIZATION_REQUIRED"}
```

## 3. 結論

Amazon API Gatewayでは`WWW-Authenticate`レスポンスヘッダを返すことができないため、***Webブラウザから***HTTP Basic認証を行うことができない。おそらく、HTTP Digest認証も同様と思われます。