「Identity Developer Trainiing Kit のインストールがうまくいかなくて泣いているのは、どこのどいつだ~い?あたしだよ。(西岡風)」
というわけで、Windows Identity Foundation(WIF)を使用して Windows Azure アプリケーションを開発する手法を学習するのに最適なツールがあります。
それが、
Identity Developer Training Kit (最新版は 2010年6月版)
です。
これには、様々なパターンの Identity 関連アプリケーションのデモサンプル+Step By Step ガイド(英語)が含まれていて、とても良さげなのですが、日本語環境にインストールしようとすると、どうもうまくいきません。
一見正常に終わったように見えるのですが、Visual Studio を起動してプロジェクトを開くと、以下のようなエラーが発生します。
ソリューション内の1つ以上のプロジェクトが正しく読み込まれていません。詳細については出力ウィンドウを確認してください。
ということで、Visual Studio の出力ウィンドウを確認してみると、以下のように WEBサイトが開けないというエラーが出ています。
https://localhost/ClaimsEnableWebSiteEx01 : error : Web サイト https://localhost/ClaimsEnableWebSiteEx01 が開けません。ローカル IIS Web サイトにアクセスするには、次の IIS コンポーネントをインストールする必要があります:
(注意)”ClaimsEnableWebSiteEx01” 部分は、開くプロジェクトによって異なります。
実はセットアップ時に表示されるコマンドプロンプトを目を見開いてみていると、エラーが発生していることがわかります。
「パラメーターが間違っています」というエラーが出ていることがわかります。どうやら原因はこいつにありそうなので、スクリプトを開いてデバッグしてみましょう。
今回は、Identity Develper Training Kit の中の「WebSitesAndIdentity」というサンプルプロジェクトに対して対処してみます。
まずは、以下のファイルを開いてください。
C:\IdentityTrainingKit2010
\Labs
\WebSitesAndIdentity
\Source
\Setup
\Scripts
\SetupCertificates.cmd
開いたものを以下に示します。ちょっと長いですが、単なるバッチファイルであることがわかります。
問題になっているのは、以下のバッチファイルの「httpcfg.exe set ssl -i 0.0.0.0:443 -f 2 -h %CERTHASH%」です。httpcfg.exe コマンドの引数である %CERTHASH% が空っぽだったために、エラーになっていたのです。
じゃ、空っぽの原因はどこにあるかというと、以下のバッチファイルの「Cert Hash(sha1)」部分です。
SetupCertificates.cmd
| @echo off echo. echo ================================================================ echo WARNING: This setup script will replace the existing "localhost" echo certificate. If you have applications that uses the current echo localhost certificate, remember to create a backup copy of it echo before continue with this setup. echo ================================================================ echo. REM choice /m "Do you want to proceed with the certificates installation" REM if ERRORLEVEL 2 goto :end echo Installing CAPICOM... echo. msiexec /qn /i "%~dp0capicom_dc_sdk.msi" call "%~dp0CleanupCertificates.cmd" echo Installing certificates... echo. set IsWinClient=false echo certutil -f -addstore Root "%~dp0certs\localhost.cer" certutil -f -addstore Root "%~dp0certs\localhost.cer" IF EXIST "%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK" ( regsvr32 /s "%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Lib\X86\capicom.dll" SET capicompath="%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs" SET cscript=%windir%\system32\cscript.exe ) IF EXIST "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK" ( SET capicompath="%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs" SET cscript=%windir%\syswow64\cscript.exe ECHO Setting up CAPICOM for 64 bits environment... copy /y "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Lib\X86\capicom.dll" %windir%\syswow64 %windir%\syswow64\regsvr32.exe /s %windir%\syswow64\capicom.dll ) %cscript% /nologo %capicompath% import -l LM "%~dp0certs\localhost.pfx" "xyz" %cscript% /nologo %capicompath% import -l LM "%~dp0certs\IdentityTKStsCert.pfx" "IdentityTKStsCert" %cscript% /nologo %capicompath% import -l LM -s trustedpeople "%~dp0certs\IdentityTKStsCert.pfx" "IdentityTKStsCert" @set IsW7= (ver | findstr /C:"6.1") && set IsW7=true @if "%IsW7%" == "true" ( "%~dp0winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s localhost -a "IIS_IUSRS" "%~dp0winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s IdentityTKStsCert -a "IIS_IUSRS" set IsWinClient=true ) else ( "%~dp0winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s localhost -a "NETWORK SERVICE" "%~dp0winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s IdentityTKStsCert -a "NETWORK SERVICE" ) for /f "tokens=2,* usebackq" %%a in ( `certutil -store my localhost ^| findstr /c:"Cert Hash(sha1)"` ) do ( set CERTHASH=%%b ) if NOT "%CERTHASH%" == "" ( set CERTHASH=%CERTHASH: =% ) set IsVista= (ver | findstr /C:"6.0") && set IsVista=true if "%IsWinClient%" == "false" ( set IsWinClient=%IsVista% ) if "%IsWinClient%" == "true" ( ECHO Setting up SSL at port 443 using localhost certificate... netsh http delete sslcert ipport=0.0.0.0:443 > nul netsh http add sslcert ipport=0.0.0.0:443 appid={00000000-0000-0000-0000-000000000000} certhash=%CERTHASH% clientcertnegotiation=enable ) else ( ECHO Importing server certificate and point HTTP.SYS at it... httpcfg.exe delete ssl -i 0.0.0.0:443 > nul httpcfg.exe set ssl -i 0.0.0.0:443 -f 2 -h %CERTHASH% ) "%~dp0IIS7Util.exe" SetSslCert %CERTHASH% IISReset echo. echo ============================ echo Certificates Setup finished! echo ============================ pause :end |
以下は、問題部分となっている部分です。何をしているかわかりますか?
for /f "tokens=2,* usebackq" %%a in ( `certutil -store my localhost ^| findstr /c:"Cert Hash(sha1)"` ) do (
set CERTHASH=%%b
)
certutil.exe コマンドで、ローカルホストに登録されている証明書の一覧を出力しています。
ここで、findstr に注目してください。findstr コマンドでは、certutil の出力結果から「Cert Hash(sha1)」という文字列を探し出して、同じ行に出力されるはずの証明書のハッシュ文字列を取り出し、CERTHASH という環境変数に格納しようとしています。
なんでこれがエラーになるのか?
以下の画面ショットをご覧ください。これは、certutil コマンドを単独で入力したときの出力結果(例)です。赤枠で囲んだ部分に目を凝らしていただくと、なんと「 Cert ハッシュ(sha1) 」と日本語で出力されていることがわかります。
原因はまさにこれです。
よって、バッチファイル SetupCertificates.cmd を以下のように修正してあげることで正しく動作するようになります。
for /f "tokens=2,* usebackq" %%a in ( `certutil -store my localhost ^| findstr /c:"Cert ハッシュ(sha1)"` ) do (
set CERTHASH=%%b
)
やり直す場合には、一度 Cleanup.cmd を実行して環境をきれいにした後で再実行してください。
なんとも馬鹿げたトラブルですが、まぁ、ありがちといえばありがちではあります…orz。
こんなトラブルが発生したときには、ITPROでよかったなぁ、と心から思うのでありました。