Application GatewayでCORSヘッダーを返してみよう
2020-12-09
azblob://2022/11/11/eyecatch/2020-12-09-lets-use-agw-to-return-the-cors-header-000.jpg

この記事はFIXER 3rd Advent Calendar 2020 ( https://adventar.org/calendars/5928 ) 9日目の記事です。
前日はこちらです(https://tech-blog.cloud-config.jp/2020-12-08-power-apps-portal-webservice/)。PowerApps良いですよね、必要に応じて細かい改修ができることを初めて知りました。そろそろこちらも勉強しないと・・・

AzureのApplication Gatawayは様々な機能を持っています。
その中で、通信のHTTPリクエスト・レスポンスを書き換える機能があります。
これを使用することで、例えばいわゆるCORSヘッダーを返却することができます。CORSヘッダーはアプリレイヤー等で設定することもできますが、Application Gatawayに任せればterraformで構築するとコードで定義されて別環境構築時にも便利ですよね。
今回はその辺りを解説したいと思います。

HTTPヘッダーの追加には「書き換えセット」を使う

CORSヘッダーについて簡単に説明します。
Access-Control-Allow-Origin をレスポンスヘッダーに含めると、ブラウザが「ほかのドメインにデータ取りに行ってるけど、そのサーバーはこのアクセスを許容しているんだな」と判断して処理を継続してくれる仕組みですね。
レスポンスヘッダーはアプリ側で設定することもできますが、業務処理の本質ではないのでミドルウェアレイヤー等で対応するのも一つの手だと思います。
これがApplication Gatawayでできる、というお話になります。

まずはAzureでApplication Gatawayを用意してください。この時に書き換えセットが使えるよう、レベルをV2 ( Standard V2かWAF V2 ) にしてください。

Application Gatawayが用意できたら、Azureポータルで「書き換えセット」から「+書き換えセット」を選び、名前と割り当て先のルーティング規則を指定し、「書き換えルールの構成」に進みます。
「書き換えルールの構成」で「結果」のところを下記のように設定すると、CORSヘッダーが返せます。

書き換えの種類応答ヘッダー
アクションタイプ設定
ヘッダー名共通ヘッダー
共通ヘッダーAccess-Control-Allow-Origin
ヘッダー値*

条件指定をすれば、特定のOriginからのアクセスだけCORSヘッダーを返すようにできる

上記でCORSヘッダーは返せるものの、「誰でもWelcome」状態なのでセキュリティも何もない状態です。
特定のOriginからのアクセスのみ、CORSヘッダーを返すのが筋ですよね。
これも簡単で、書き換えセットの設定に条件を追加します。「書き換えルールの構成」で「+条件の追加」を押してください。下記のように設定します。

チェックする変数の型HTTPヘッダー
ヘッダーの種類要求ヘッダー
ヘッダー名共通ヘッダー
共通ヘッダーOrigin
大文字と小文字を区別するいいえ
演算子等しい(=)
一致させるパターン.*fixer\.co\.jp など、許可対象のOriginを示す正規表現

Originは正規表現で記載するので、ドットをエスケープするなどして正しいものを指定しましょう。

これで、想定するドメインのWebアプリからのアクセスのみ、CORSヘッダーが返るようになりました。設定項目が多く見えますが、分かれば簡単ですね!

terraform実装時のポイント

だいたいこんな記述が追加されることになると思います。

resource "azurerm_application_gateway" "this" {
  (略)
  request_routing_rule {
    name                       = xxx
    rule_type                  = "Basic"
    http_listener_name         = xxx
    backend_address_pool_name  = xxx
    backend_http_settings_name = xxx
    rewrite_rule_set_name      = "rewrite-rule-1"
  }

  rewrite_rule_set {
    name = "rewrite-rule-1"

    rewrite_rule {
      name          = "rule1"
      rule_sequence = 100

      condition {
        variable    = "http_req_Origin"
        pattern     = ".*fixer\\.co\\.jp"
        ignore_case = true
        negate      = false
      }

      response_header_configuration {
        header_name  = "Access-Control-Allow-Origin"
        header_value = "*"
      }
    }
  }
}

request_routing_rule の rewrite_rule_set_name に書き換えセット名を入れること、rewrite_rule_set のpattern で正規表現のバックスラッシュ自体をエスケープすること、くらいがポイントです。

もしエラーが出たりする場合は、Azureポータルで「テンプレートのエクスポート」を押して見えてくるARMテンプレートと比較するのも、エラー解決のヒントになります。

まとめ

Application Gatawayを使えばCORSヘッダーを簡単に返せること、条件指定もできることが分かったと思います。
CORSヘッダーに限らず、ほかのレスポンスヘッダーも制御できるので調べてみてください。
インフラレイヤーで制御ができるとIaC化ができるので、管理・応用しやすくなりますね。ぜひ活用していきましょう!