2011年4月24日日曜日

IIS ExpressでSSLを有効にしてデバッグ

Working with SSL at Development Time is easier with IISExpress - Scott Hanselman

Hanselmanさんのエントリに書かれてる通りデス!

IIS ExpressでSSLを有効にしたデバッグだと無効な証明書だと警告はでるけど、HTTPSでのテストはコレでできますよね。

だけど、名前はlocalhostに限定です。これはまぁ、そういうバインドしかapplicationHost.configに登録してないからなのと、アクセス許可をしてなからなんですが(詳しくはmvcConf 2 - Vaidy Gopalakrishnan: IIS Express | mvcConf | Channel 9)、その辺をちゃんと登録して気持ちよく使いましょうという内容ですね。途中URLRewriteでAccountControllerへのアクセスをHTTPSに書き換えるというのが挟まってるけど、コードで対応するならここは飛ばしてもOKです。

netshへのcerthashの登録、信頼されたルート証明機関の証明書として証明書を登録、最終的にIisExpressAdminCmdでACLの許可登録で気持よく、マシン名でもSSL有効な状態でアクセスできます。

というのを、自分の環境でも確認してみましょう。

1.ASP.NET MVCサイトを作成

もちろんVS2010で行うのが簡単ぽんなんですが、VS2008でも同じようにできるので(applicationHost.configとnetshなので)、そっちしかない場合はそっちで。プロジェクトの設定で、外部プログラムを起動するを利用しましょう(IIS ExpressのVS2008/VS2010利用)。

今回は簡単なVS2010で新しくなったMVC3 Toolsで作ります。

ssl1

いい感じにHTML5ですね!

2.プロジェクトのプロパティでSSL有効化

ssl2

trueにするだけの簡単な作業です。これでSSL URLが入ります。この例だと https://localhost:44301/ ですね。

この状態でまずは実行してみましょう。

ssl3

文句は言われるけど、普通に問題なくアクセスできますね。楽チンデス。IIS Express最高!

3.localhostじゃなく好きな名前でアクセス

マシン名でもいいんですが、そこはほら、恥ずかしい名前付けてる場合もあるじゃないですか。そんな状態で表示するのもどうかと思うわけですよ。なので、今回は完全カスタムな名前にしてしまいます。

takepara-local

という名前にします。これが恥ずかしい名前じゃないかと言われると、まぁ微妙ですが。あ、ちなみに自分のマシン名はそんなに恥ずかしい名前じゃないですよ。

IisExpressAdminCmdでアクセスできるようにしましょう。

※”.”でドメインな感じのマシン名だとsetupFriendlyHostnameUrlに失敗します。

ssl6

これでブラウザからアクセスしてみましょう!

ssl7-2

残念。エラーです。何か忘れてますね。そうですね、applocationHost.configにバインド登録してなかったですね。

<site name="SslTest" id="15">
    <application path="/" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="..." />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:51578:localhost" />
        <binding protocol="https" bindingInformation="*:44301:localhost" />
        <binding protocol="http" bindingInformation="*:80:takepara-local" />
        <binding protocol="https" bindingInformation="*:443:takepara-local" />
    </bindings>
</site>

ssl7

グレートですね。ちなみにhostsにtakepara-local登録して、netshでurlacl登録しても一緒です。

このまま、調子にのってHTTPSにしてみる。

ssl8

残念。ダメでした。

4.証明書を作成

takepara-localの証明書を作成してませんでしたね。hanselmanさんのエントリに書かれてるとおりです。makecertしましょう。CNだけ変えて後はそのままで。

ssl9

makecert -r -pe -n "CN=TAKEPARA-LOCAL" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

VSコマンドプロンプトから実行しましょう。パス通ってて確実。

ssl10

証明書をnetshで登録。

netsh http add sslcert ipport=0.0.0.0:443 appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certhash=864759f75a04d030e243ecf1cfe19ce336653374

ssl11ssl12

警告でるけど、気にせず表示。

5.証明書を信頼

このままでもいいんですが、やっぱり気持よく。

ssl13

信頼しちゃいましょう。自分のマシンで、自分で作った証明書。信頼しちゃえばいいじゃないか!

ssl14

Chrome厳しす。まぁ、いいか。警告でなくなったしね!

6.Accountコントローラを厳しく

URLRewriteで同じようになってもいいんですが、あえてコードで対応しましょう。と、言っても難しいことはなく、AccountControllerにRequireHttps属性を付けるだけ。

ssl15

これで、AccountControllerへのアクセスがHTTPSになってなければ、リダイレクトされます。リダイレクトされるということはHTTPでのPOSTは無視される(リダイレクトはGETデス)ので、気をつけましょう。

ssl16

この動きが気持ち悪いときはViewでURLを埋め込むときにHTTPSにしてあげる必要があるので、修正箇所が随分増えちゃいますが、通常の開発であればViewでもちゃんと書いて、ControllerへのRequireHttpsも付ける2段構えになるのが王道でしょう。抜け道なし。ViewのURLなんて嘘つくからね。

例えば、_LogOnPartial.cshtmlを以下のようにする。

@if(Request.IsAuthenticated) {
    <text>Welcome <strong>@User.Identity.Name</strong>!
    [ @Html.ActionLink("Log Off", "LogOff", "Account", "https", "takepara-local", "", null, null) ]</text>
}
else {
    @:[ @Html.ActionLink("Log On", "LogOn", "Account", "https", "takepara-local", "", null, null) ]
}

これで、必ずHTTPSのURLが生成されます。

画像てんこ盛りですが、手順通りやればうまくいくので、HTTPSでのテストをやりたい場合は是非どうぞ。

なんか、うまくできない!という場合はタスクトレイのIIS Expressを終了させてやり直してみるといいかも。applicationHost.config書き換えしたときなんかは特に。