しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

URL Rewrite の Outbound Rule を使って HTTP レスポンスヘッダを書き換える

IIS の URL Rewrite でリクエストの Origin を見て Access-Control-Allow-Origin を書き換えることが出来ないか調べました。仕様的にはスペース区切りで複数のオリジンを定義出来るみたいなんですが、どうも実装がまだ追いついていないブラウザもあるようなので。*1

少しそれっぽいキーワードで調べてみると、公式サイトやブログなどで色々と情報が見つかりました。

URL Rewrite Module 2.0 Configuration Reference : The Official Microsoft IIS Site

Modifying HTTP Response Headers : The Official Microsoft IIS Site

Change or modify a Response Header value using URL Rewrite - benjamin perkins - Site Home - MSDN Blogs

読んでみると Outbound Rule を使えば HTTP レスポンスヘッダを書き換えることが出来るらしい。

というわけで今回は URL Rewrite を使って CORS に必要な Access-Control-Allow-Origin を書き換える定義を作成してみます。とりあえず IIS Manager で送信規則を新しく作成して、サーバー変数を書き換えるとレスポンスヘッダを書き換えることが出来るようです。

必須条件として Origin ヘッダを見る条件を新しく作成します。

f:id:shiba-yan:20150126154353p:plain

この条件を無くすと、全てのクロスドメインリクエストに対して対応する Access-Control-Allow-Origin を出力するように出来ますが、それはいまいちなので条件で縛ります。

そして一致するスコープとしてサーバー変数を選んで、RESPONSE + "_" + HTTP ヘッダ名というサーバー変数名を指定すれば、書き換えるための準備完了です。

f:id:shiba-yan:20150126151901p:plain

HTTP ヘッダ名のハイフンはアンダースコアに置換しておいた方が安全な気がしました。*2

最後にアクションとして書き換えを選んで、HTTP_ORIGIN で書き換えるようにすれば完了です。

f:id:shiba-yan:20150126152359p:plain

既存のサーバー変数値を書き換えるという設定が重要な気がしましたが、デフォルトでオンなので安心。

IIS Manager で追加した結果、Web.config に追加される定義は以下のような感じ。

<rewrite>
  <outboundRules>
    <rule name="Modify CORS" preCondition="IsAnotherSite" patternSyntax="Wildcard">
      <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern="*" />
      <action type="Rewrite" value="{HTTP_ORIGIN}" />
    </rule>
    <preConditions>
      <preCondition name="IsAnotherSite">
        <add input="{HTTP_ORIGIN}" pattern="http://sub\.example\.com" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>

Access-Control-Allow-Origin に * を指定してしまうとクロスドメイン時にクッキーが送信されなくなるので、Origin ヘッダを見て書き換えるような実装にしました。

URL Rewrite だとこういった処理は書けないと思っていたので、良い機能を知ることが出来て満足です。