AWSで複数オリジンのホワイトリストチェックするAPIを実装する

Pocket

はじめに

こんにちは!山内です。先日とあるAPIをAWSで実装していた時に、「いくつかのオリジンからのアクセスのみ許可したい」というリクエストがありました。Webアプリを構築する際にCORS設定のため似たようなことをAPI Gatewayでやっていたので、楽勝だ~って思って二つ返事で了承しました。ところが、API Gatewayが複数オリジンの許可設定を書けない仕様らしく、意外と面倒だったので忘れないように記事にしようと思います。

API Gatewayでのオリジンアクセス許可設定

本題に入る前に、そもそもAPI Gatewayでオリジンアクセス許可ってどうやるんだっけというところを再確認しておきます。次の手順で実現できます。

  1. 「リソース」>「アクション」>「CORSの有効化」をクリックする

以上です!とっても簡単ですね!設定時にポップアップが出てくるとは思いますが、操作は簡単でも裏で色々設定をしてくれています。関連記事がたくさんあるはずなので、興味のある方は調べてみてくださいね。

複数オリジンのホワイトリストチェック

では、本題に入ります。実は、上記の設定で全てのオリジンからのアクセスも許可する設定はできてしまっています。それは、APIの対象リソース、「OPTIONS」>「統合レスポンス」>「▶(メソッドレスポンスのステータスが200となっている行)」>「▶(ヘッダーのマッピング)」から確認できます。

「Access-Control-Allow-Origin」の値が「*」になっていると思います。これにより、どのオリジンからのアクセスも許可ができているということです。

最初は、この値をカンマなりセミコロンなりで複数書けばいけるだろうと思っていたのですが、なんとこの値、そういう書き方はできないんだそうです。こいつは困った~!って思って色々調べた結果、「*で受け付けておいて、Lambdaでホワイトリストチェックする」というのが最適解でした。その実装(Python3.8)は次の通りです。

コード解説

短いコードですが、3つポイントがあるので簡単に各部分のコード解説をします。

環境変数へのアクセス

12行目のコードでLambda環境変数からホワイトリストを取得しています。今回はカンマ繋ぎで登録しているため、カンマで分割してリストに格納しています。

オリジン情報の取得

29行目のコードでLambdaのイベントデータに含まれるオリジン情報を取得しています。ちなみに以前、オリジン情報を使う実装をしていたAPIに対して、JMeterでパフォーマンステストをしたところ、JMeterがオリジン情報を送信しないため、エラーとなったことがありました。ツールによってはそういうこともあるので、考慮しましょう。

レスポンスヘッダーの設定

30~34行目のコードでレスポンスヘッダーを設定しています。この時、取得したオリジン情報をそのまま設定します。こうすることで、全てのオリジンからのアクセス許可をせずに、特定の複数のオリジンに対してのみ正常にレスポンスを返すことができます。この実装の中では一番のポイントです。

動作確認

動作確認のため、S3の静的Webホスティングを使って、次の2つのオリジンを用意します。

  • whitelist-check-sample-ok(Lambda環境変数のホワイトリストに含まれている)
  • whitelist-check-sample-ng(Lambda環境変数のホワイトリストに含まれていない)

それぞれのS3バケットには次のindex.htmlを用意します。許可されているかされていないかのメッセージがそのまま表示されるようにしています。なお、このコードの内容は本記事の主旨とは離れているので、解説は割愛します。

まずはホワイトリストに含まれている、whitelist-check-sample-okにアクセスしてみます。

期待通り、「許可されたオリジンです。」というメッセージが表示されました。
Chromeの開発者ツールの「Network」タブでリクエストとレスポンス情報も見てみましょう。

リクエストヘッダー「Origin」に含まれている「https://whitelist-check-sample-ok.s3-ap-northeast-1.amazonaws.com」がそのままレスポンスヘッダー「Access-Control-Allow-Origin」にも含まれていることが確認できました。

次に、ホワイトリストに含まれていない、whitelist-check-sample-ngにアクセスします。

こちらも期待通り、「許可されたオリジンではありません。」というメッセージが表示されました。
同様にリクエストとレスポンス情報を見ます。

リクエストヘッダー「Origin」に含まれている「https://whitelist-check-sample-ng.s3-ap-northeast-1.amazonaws.com」がそのままレスポンスヘッダー「Access-Control-Allow-Origin」にも含まれていることが確認できました。

おわりに

今回の記事は以上で終わりです。AWSはデモを作るにも簡単で良いですね、今回使った環境はコード実装含めても30分ほどで構築完了できました!ただ、複数オリジンのホワイトリストチェックって要件としては結構あり得るケースだと思うので、まだまだ痒い所に手が届かない部分もあります。しかしながら、今回の件を解決するにあたって公式に問い合わせしたときに、既に承知の内容だったので、待っていればそのうちカイゼンされるかもしれませんね。どんどんカイゼンされていくのもクラウドサービスの良さの1つだと思うので、もっと積極的に活用していきましょう!

お問い合わせ先

執筆者プロフィール

Yamauchi Kentaro
Yamauchi Kentarotdi デジタルイノベーション技術部
社内の開発プロジェクトの技術支援や、Javaにおける社内標準フレームワークの開発を担当しています。Spring BootとTDDに手を出しつつ、LINE Botとかもいじったりしています。最近はマイクロサービスを勉強しつつ、クラウドアプリケーションを開発できるエンジニアの育成にも力を入れてます!
Pocket

関連記事