作成者: Thomas Deml
はじめに
Windows 7 または Windows Server 2008 R2 の IIS 7.5 では、"アプリケーション プール ID" という新機能がサポートされています。 これにより、サンドボックス化されるアプリケーション プールごとにユーザー アカウントを維持する必要がなく、アプリケーション プールを効果的に分離できます。 アプリケーション プール ID は自動的に生成され、パスワードも必要ないため、管理コストが削減されます。
すべての新機能と同様に、特定の欠点があり、これはアプリケーション プール ID 機能でも変わりません。 この記事では、IIS 7.5 を SQL Express と共に使用するときに Web アプリケーション開発者が直面する可能性がある問題について説明します。
パズルのピース
SQL Express では、"ユーザー インスタンス" または RANU (通常のユーザーとして実行) と呼ばれる機能がサポートされています。この機能が有効になっている場合 (接続文字列に "UserInstance=true" を追加するだけで簡単に有効にできます)、ユーザーがデータベース接続を開いたときに開始される SQL Server プロセスは、接続しているユーザーと同じアカウントで実行されます。 RANU は、セキュリティの観点から非常に望ましいものです。
Visual Studio 2008 または Visual Studio 2010 を使用して開発している場合、既定の接続文字列が machine.config ファイルに格納されます。 次のとおりです。
<connectionStrings>
<add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
...
既定の接続文字列は、ご覧のように RANU (User Instance=true) を使用しています。 既定の接続文字列は、たとえば、機能でデータベースにデータを格納する必要があるが、データベースがまだ構成されていない場合などに使用されます。 ASP.NET メンバーシップは、この良い例です。 開発者が Web アプリケーションにメンバーシップ機能を追加すると ASP.NET は machine.config 内の既定の接続文字列を使用して、データベースと必要なテーブルを自動的に作成します。
問題
ここで問題が発生します。
すぐに使える RANU は、新しい "アプリケーション プール ID" 機能では機能しません。 "アプリケーション プール ID" 機能は、IIS 7.5 の既定の ID です。 たとえば、IIS 7.5 DefaultAppPool は"IIS AppPool\DefaultAppPool ID" の下で実行され、NetworkService では実行されません。 このため、Visual Studio を使用して開発している場合は、この問題が発生する可能性があります。
表示される可能性のあるエラー ページを次に示します。
このエラーは、SQL Server Express RANU でユーザー プロファイルを読み込む必要があり、IIS 7.5 が既定でユーザー プロファイルを読み込まないために発生します。 以前のバージョンの IIS では、DefaultAppPool が NetworkService として実行されており、オペレーティング システムによって NetworkService のユーザー プロファイルがプリロードされるため、このエラーは表示されません。
修正プログラム
幸いにも、この問題の修正は非常に簡単です。 IIS では、アプリケーション プールの LoadUserProfile 設定を true に設定するだけで、アプリケーション プールのユーザー プロファイルを読み込むことができます。
これは、ユーザー インターフェイスから次のように実行できます。
- IIS マネージャーで "アプリケーション プール" ノードをクリックします。
- 問題のアプリケーション プール (DefaultAppPool など) を選択します
- 右側の [アクション] メニューで "詳細設定..." をクリックします。
- "プロセス モデル" サブセクションに "ユーザー プロファイルの読み込み" という名前の行があります。 "true" に切り替える
コマンド ラインを使用してこれを行う場合は、管理者特権のコマンド プロンプトで次のコマンドを実行します。
%windir%\system32\inetsrv\appcmd set config -section:applicationPools /[name='DefaultAppPool'].processModel.loadUserProfile:false
ユーザー プロファイルの読み込みの副作用
ユーザー プロファイルを読み込む場合の最大の副作用は、一時ディレクトリです。 ユーザー プロファイルが読み込まれていない場合、%temp% 環境変数は \windows\temp ディレクトリを指します。 すべてのユーザーがこのディレクトリに書き込むことができます。 ユーザー プロファイルが読み込まれる場合、%temp% 環境変数は、ユーザーのみがアクセスできる専用ディレクトリを指します。 したがって、DefaultAppPool が "IIS AppPool\DefaultAppPool" として実行されている場合、%temp% 変数は C:\Users\DefaultAppPool\AppData\Local\Temp
ディレクトリを指します。 このディレクトリには、DefaultAppPool と管理者のみが書き込みアクセス権を持ちます。
では、なぜこれが問題なのでしょうか。 残念ながら、Windows オペレーティング システムでは "偽装" と呼ばれる機能がサポートされています。 偽装を使用すると、プロセスが実行している ID とは異なる ID でコードの一部を実行できます。 一部の Web アプリケーション フレームワークでは、この機能を利用しています。 たとえば、従来の ASP では、すべてのコードが偽装として実行されます。 使用される ID は、IIS 構成ストアで構成された匿名ユーザーか、IIS が提供する認証スキーム (Basic、Digest、または Windows) を介して認証されたユーザーのいずれかです。 ASP.NET は、既定で実行されるコードを偽装しません。 偽装は、構成で system.web ID セクションを使用するか、.NET API を使用して引き続きサポートされます。 問題は、偽装された ID が %temp% ディレクトリにアクセスできない可能性があるということです。 この問題の 1 つのインスタンスについて説明する記事を次に示します。
ASP.NET アプリケーションのみを開発し、ID セクションを使用しない場合は、おそらくこれらの問題が発生することはなく、ユーザー プロファイルの読み込みは完全に安全であるはずです。
まとめ
この記事では、SQL Express と新しい IIS 7.5 アプリケーション プール ID に関する問題について説明しました。 IIS 7.5 ユーザーではアプリケーション プール ID 機能が既定であるため、開発環境で SQL Express を使用する場合、つまり Visual Studio を使用して開発するときに、上記の問題が発生する可能性があります。 運用環境では SQL Express がサポートされていないため、運用環境ではこの問題は発生しません。