WebSurfer's Home

Filter by APML

URL Rewrite Module で HTTP を HTTPS へリダイレクト

by WebSurfer 13. December 2024 19:02

先日 Let's Encript を利用してHTTPS 通信ができるようにしたのを機会に、ホスティングサービスに実装されている IIS の URL Rewrite Module を使って、HTTP で要求が来た場合は 301 Moved Permanently 応答を返して HTTPS にリダイレクトするように設定しました。

ネットで検索してヒットする記事の中では Redirect HTTP to HTTPS with Windows IIS 10 が一番信頼できると思います。実際その通りやって期待通りの結果が得られます。

ですが、自分の Windows 10 PC のローカル IIS で一通りやってみました。さらに、設定がどのような意味を持つかも調べました。調べて分かったことを以下に備忘録として書いておきます。

さらに詳しく知りたい場合は、Microsoft のドキュメント「URL リライト モジュール構成リファレンス」を見ることをお勧めします。日本語版は翻訳がアレなので意味不明なところがあると思います。その場合は英語版を読んでください。

(1) URL Rewrite Module の起動

URL Rewrite Module の起動

IIS Manager を起動して書き換えを行うサイトまたはアプリケーションを選び、IIS メニューの[URL Rewrite]をクリックします。

(2) 書き換えルールの追加

書き換えルールの追加

画面右側の「操作」欄の下のメニュー[Add Rule(s)...]をクリック。それにより表示された「Add Rule(s)」ダイアログの「Inbound rules」下の「Blank rule」を選択して[OK]ボタンをクリックします。

(3) Match URL セクション

Match URL セクション

上の「Edit Inbound Rule」画面が表示されます。赤枠で示したように[Name]に任意の名前を入力し、Match URL セクションの[Pattern:]に正規表現 (.*) を入力します。その他はデフォルトで上の画像の通りとなっているはずなので、そのままにしておきます。

設定の意味は、要求 URL が[Pattern:]に設定された正規表現 (.*) にマッチした時に Conditions に設定された条件を調べて、条件が満たされていれば Action の設定に従って処理を行うということです。正規表現 (.*) はどのような URL にもマッチします。

正規表現を ( ) で囲うのは意味があって、今回の例では使っていませんが、パターンをグループ化して入力の特定の部分を {R:0} とか {R:1} で取得できるからです。

[Ignore case]というのは大文字・小文字の区別をしないという意味です。チェックが入ったままにしておいてください。

(4) Conditions セクション

Conditions セクション

Conditions セクションを開いて[Add...]ボタンをクリックし、表示された「Add Condition」ダイアログで[Condition input:]と[Pattern:]に赤枠で示した通り入力します。その他はデフォルトで上の画像の通りとなっているはずなので、そのままにしておきます。

[Condition input:]に入力した {HTTPS} は、上に紹介した Microsoft のドキュメントにも書いてありますが、サーバー変数です。HTTPS 通信でない場合サーバー変数 {HTTPS} の値は OFF という文字列になります。

つまり、サーバー変数 {HTTPS} の値が[Pattern:]に入力した正規表現 ^OFF$ にマッチした場合は HTTPS 通信でないと判断され、Action に設定されるリダイレクトが実行されるということです。

Conditions セクションの入力・設定が完了したら[OK]ボタンをクリックします。結果は以下のようになるはずです。

設定された条件

(5) Action セクション

Action セクション

上の画像の赤枠で示した通り設定・入力します。その他はデフォルトで画像の通りとなっているはずなので、そのままにしておきます。

[Action types:]の設定[Redirect]でリダイレクトを行う応答(この記事では 301 Moved Permanently)が返されます。

[Redirect URL:]に設定した {HTTP_HOST} と {REQUEST_URI} はサーバー変数です。上に紹介した Microsoft のドキュメントにも書いてありますが、例えば要求 URL が以下の場合、

http://www.mysite.com/content/default.aspx?tabid=2&subtabid=3

取得される文字列はそれぞれ以下のようになります。

  • HTTP_HOST: www.mysite.com
  • REQUEST_URI: /content/default.aspx?tabid=2&subtabid=3

[Append query string]のチェックは外しておきます。[Redirect URL:]に設定した REQUEST_URI にクエリ文字列は含まれるので不要なはずです。

[Redirect type:]はデフォルトで[Permanent (301)]となっているはずなのでそのままにしておきます。今回のような HTTP から HTTPS へのリダイレクトでは 301 Moved Permanently が SEO 的に望ましいそうです。

(6) ルールの適用

ルールの適用

入力・設定が完了したら右側の「操作」欄の下のメニュー[適用]をクリックします。

(7) web.config

アプリの web.config に以下のコードが追加されているはずなので確認してください。

<system.webServer>
  <rewrite>
    <rules>
      <rule name="Redirect HTTP to HTTP" stopProcessing="true">
        <match url="(.*)" />
        <conditions>
          <add input="{HTTPS}" pattern="^OFF$" />
        </conditions>
        <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" 
                appendQueryString="false" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

(8) ブラウザで確認

ブラウザで確認

ブラウザのキャッシュを削除してからアドレスバーに http で始まる URL を入力して要求をかけ、上に設定したとおりリダイレクトが行われるか確認してください。

上の画像は Chrome のディベロッパーツールの Network でキャプチャした要求・応答を見たものです。設定どおり 301 Moved Permanently 応答が返ってきて、https で始まる URL にリダイレクトされています。

確認後、上の (7) の xml コードをホスティングサービスのサイトの web.config にコピーします。結果、期待通り HTTP から HTTPS へリダイレクトされることが確認できました。

Tags: , ,

Windows Server

URL Rewrite Module の Outbound Rules

by WebSurfer 20. March 2017 16:56

gzip 圧縮済みのコンテンツを応答としてブラウザに返す場合、下の画像のように応答ヘッダに Content-Encoding: gzip を設定する必要があります。

応答ヘッダ

HTTP ハンドラを使って自分でダウンロードするコードを書く場合は自由���応答ヘッダを追加できますが、IIS の静的ハンドラを使う場合(例えば、img 要素の src 属性に .svgz 画像のパスを設定したような場合)はどうすればいいでしょう?

URL Rewrite Module 2.0 の Outbound Rules を利用すると応答ヘッダに Content-Encoding: gzip を設定できます。.svgz 画像の場合を例にとって以下にその方法を書きます。(注: Content-Type: image/svg+xml も必要ですが applicationHost.config の MIME Map で設定済みであれば何もする必要はありません。IIS Manager で調べてください)

URL Rewrite Module の Outbound Rules

IIS Manager を起動して、上の画像のように Add Rule(s) ダイアログで Outbound Rules の Blank rules を選択し、OK ボタンをクリックすると Edit Outbound Rule という編集画面が開くので、そこでまず Precondition を定義します。

Precondition の定義

上の画像は Precondition の名前を IsSVGZ とし(任意)、Server Variable の URL(クエリ文字列等を含まないベースの部分)が正規表現の \.svgz$ にマッチする(.svgz で終わる)という条件になっています。URL の代わりに PATH_INFO を使っている記事がありますが、 ASP.NET の場合はどちらも同じ結果になりますので、分かりやすいと思われる URL を使用しました。

Precondition 設定後 Edit Outbound Rule 編集画面に戻って、Rule 名(任意)と Match 条件を設定します。下の画像の赤枠で囲った部分を見てください。

Name と Match の設定

Server Variable 名の RESPONSE_CONTENT_ENCODING と言うのは、Microsoft の公式文書には見つかりませんでしたが、応答ヘッダの Content-Encoding になるようです。正規表現の .* は 0 個以上の任意の文字という意味です。

ちなみに、RESPONSE_ が頭に付いている Server Variables には、RESPONSE_CONTENT_ENCODING 以外に、以下の画像の項目があるようです。未検証未確認ですが、それらは全て URL Rewrite Module で書き換え可能かもしれません。

Action の設定

次に Edit Outbound Rule 編集画面の下の方にある Action の設定を行います。下の画像の赤枠で囲った部分を見てください。

Action の設定

上記の操作の結果、当該サイトの web.config に以下のコードが生成されます。(逆に言えば、IIS Manager を操作しなくても、web.config を編集して以下のコードを追加しても同じ結果が得られます)

 
<system.webServer>
  <rewrite>
    <outboundRules>
      <rule name="Rewrite SVGZ header" 
        preCondition="IsSVGZ" stopProcessing="true">
        <match serverVariable="RESPONSE_CONTENT_ENCODING" 
          pattern=".*" />
        <action type="Rewrite" value="gzip" />
      </rule>
      <preConditions>
        <preCondition name="IsSVGZ">
          <add input="{URL}" pattern="\.svgz$" />
        </preCondition>
      </preConditions>
    </outboundRules>
  </rewrite>
</system.webServer>

上の web.config の設定により、Server Variable の URL が .svgz で終わっている要求に対しては、応答ヘッダの Content-Encoding を gzip に書き換える(無ければ追加する)という操作が URL Rewrite Module によって行われ、一番上の画像で示したように Content-Encoding: gzip が付与されます。

<注意>

URL Rewrite Module は自分でダウンロードしてインストールする必要があります。インストールしてないと web.config を書き換えても効果はありません。

Microsoft URL Rewrite Module 2.0 for IIS 7 (x64)

Microsoft URL Rewrite Module 2.0 for IIS 7 (x86)

Windows 10 にはインストールできない(レジストリの設定変更が必要)という話がありますが、その場合は、英語版しか見つかりませんが、以下のページからダウンロードしたものがレジストリの設定変更なしでインストールできます。

Microsoft URL Rewrite Module 2.0 for IIS (x64)

自分は英語版を使ったので、IIS Manager の Url Write の部分のみ英語になってしまいました。上の画像の表示は日本語版とは異なると思います。

Tags: , ,

Windows Server

二重スラッシュを含む URL 書換

by WebSurfer 23. January 2015 14:10

IIS の URL Rewrite モジュールを使用して aaaa/1/2/3 という URL を test.aspx?x=1&y=2&z=3 というように書き換えることを考えます。

URL の書き換え

この時、たとえば上の画像のように 2 つ目の値をスキップした aaaa/1//3 という URL を test.aspx?x=1&y=&z=3(y に値がないところに注目)に書き換えたい場合はどうすればいいでしょうか?

IIS7 の URL Rewrite モジュールを使って、普通に(というか、あまり深く考えずに)書換ルールを作ると以下のようにすると思います。

<rewrite>
  <rules>
    <rule name="DoubleSlash">
      <match url="aaaa/(.*)/(.*)/(.*)" />
      <action 
        type="Rewrite" 
        url="test.aspx?x={R:1}&y={R:2}&z={R:3}" />
    </rule>
  </rules>
</rewrite> 

IIS マネージャーの「テストパターン」ダイアログ上で、[テスト対象データの入力(D):]テキストボックスに aaaa/1/2/3 とか aaaa/1//3 などのテストパターンを入力してテストすると、 {R:1}, {R:2}, {R:3} には期待通りの結果が得られます。

なので、ブラウザから aaaa/1/2/3 とか aaaa/1//3 などで呼んでも同様に aaaa/(.*)/(.*)/(.*) にマッチして、test.aspx?x=1&y=2&z=3 とか test.aspx?x=1&y=&z=3 に書き換えられると期待すると思います。

しかし、ブラウザから aaaa/1//3 で呼ぶとダメです。ダメな理由は、IIS が aaaa/1//3 を aaaa/1/3 に書き換えてしまうからです。詳しく書くと以下の通りです。

  1. ブラウザからは aaaa/1//3 で要求が出る。
  2. それを受けた IIS は aaaa/1//3 を aaaa/1/3 に書き換えてしまう。
  3. aaaa/1/3 が URL Rewrite モジュールに渡される。
  4. aaaa/1/3 は aaaa/(.*)/(.*)/(.*) にはマッチしない。マッチしないので書き換えは行われない。
  5. 書き換えが行われないので、IIS は aaaa/1/3 で指定されるリソースを探す。
  6. そのようなリソースは存在しないので HTTP エラー 404.0 - Not Found となる。

ちなみに、aaaa/1/2/3 であれば期待通り test.aspx?x=1&y=2&z=3 に書き換えられ、test.aspx ページ内でクエリ文字列は正しく取得できます。

上記 2 がどうして分かったかと言うと、6 で表示されるエラー画面で「要求された URL http://aspnet4site:80/aaaa/1/3」となっていたからです。(aspnet4site は自分の開発マシンで使っているホスト名です)

というわけで、上記 2 を何とかしないと URL Rewrite モジュールでは対処できないということになります。

それを何とかする手段が IIS Server Variables の UNENCODED_URL を使用して IIS が処理する前の URL を取得して、それに書換ルールを適用することです。

詳しい手順は Microsoft IIS.net の記事 URL Rewrite Module Configuration Reference の中の「Using server variables in rewrite rules」および「Using back-references in rewrite rules」というセクションが参考になると思います。

具体的な書換ルールのコードは、今回のケースでは以下のようになります。

<rewrite>
  <rules>
    <rule name="DoubleSlash">
      <match url="^aaaa/" />
      <action 
        type="Rewrite"
        url="test.aspx?x={C:1}&y={C:2}&z={C:3}" />
      <conditions>
        <add 
          input="{UNENCODED_URL}" 
          pattern="^/aaaa/(.*)/(.*)/(.*)" />
      </conditions>
    </rule>
  </rules>
</rewrite>

上記のルールで、aaaa/1/2/3 でも、aaaa/1//3 でも、aaaa//2/3 でも、 aaaa/// でも、その他全てのパターンで期待通り書き換えられるのを確認できました。

Tags: ,

Windows Server

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。ブログ2はそれ以外の日々の出来事などのトピックスになっています。

Calendar

<<  June 2025  >>
MoTuWeThFrSaSu
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

View posts in large calendar