だから、これはただすごかった。
この問題は、次の条件がすべて当てはまる場合に発生するようです。
- Windows Server 2003 (IIS 6.0) と ASP.NET 2.0 Web サイトを実行しています。
- Web サイトは、ワーカー プロセスの最大数が 1 より大きい Web ガーデンを使用するように構成されています。このため、アウトプロセス セッション ストレージを使用するようにアプリケーションを構成しました。このシナリオでは、ローカル コンピューターで実行されている ASP.NET State Service です。
- アプリケーション プール ID は、NETWORK SERVICE ではなく、展開のベスト プラクティスに従って作成した、権限の低いカスタム ユーザー アカウントに設定されます。
- .NET フレームワークを更新するインストーラーを実行します。私の場合、これは .NET 3.0 から .NET 3.5 SP1 への更新でした。
アップグレードが完了してサーバーを再起動すると、ページの更新時にセッション変数が頻繁に失われることがわかります。これは、元の要求を処理した元のワーカー プロセスを取得できる可能性が 3 分の 1 しかないためです。ただし、ASP.NET 状態サービスを使用しているため、これは問題ではありません。何が壊れた?
ASP.NET 状態サービスを使用する場合、ASP.NET は と呼ばれる値を使用して、machineKey
格納するすべてのセッション データを暗号化および/またはハッシュします (暗号化またはハッシュ化、あるいはその両方なのかはわかりませんが、それは重要な違いではありません。この議論)。これは、ワーカー プロセスがセッション ID を使用してサービスからデータを要求したときに、データが外部データ ソースに格納されている間に改ざんされていないことを確認できるようにするためです。
Web ファームを使用している場合、おそらくファイルに static がmachineKey
定義されているためweb.config
、この問題は発生しません。ただし、単一サーバーの Web ガーデンのシナリオでは、ASP.NET 2.0 アプリケーション用にmachineKey
設定されている既定の設定を使用する可能性があります。AutoGenerate,IsolateApps
これは、ASP.NET がアプリケーション プールに固有のマシン キーを自動的に生成することを意味します。何らかのアルゴリズムに従ってこのキーを再生成しますが、それはこの説明では重要ではありません。
生成された値は、通常、レジストリの下に保存されますHKLM\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\AutoGenKeys\{SID of the Application Pool Identity}
。しかし、.NET Framework インストーラーは誤って (これはバグだと思います)、このレジストリ キーを破棄し、さらに厄介なことに、このキーのアクセス許可をリセットして、カスタム アプリケーション プール ID がレジストリ エントリに書き込むことができないようにします。新しいマシン キーを作成します。
その結果、Web ガーデンでスピンアップする各ワーカー プロセスは、ジャスト イン タイムで生成されたマシン キーの独自のメモリ内コピーを使用し、事実上、偶然に Web ファーム シナリオを作成します。たとえば、ワーカー プロセス A がスピンアップし、エントリが存在しないことを確認し (実際、それを読み取るAutoGenKey
ことさえできません)、独自のエントリを生成し、それを使用して ASP.NET State Service に送信されたデータをハッシュし始めます。この新しいマシン キーをレジストリ エントリに保存しようとしますが、黙って失敗します。ワーカー プロセス B がスピンアップし、エントリが存在しないことを確認し、独自のエントリを生成し、それを使用してデータのハッシュを開始します...これがどこに行くのかがわかります。AutoGenKey
その結果、セッション データが 3 つの異なるマシン キーでハッシュされました。セッション ID のデータは存在しますが、ワーカー プロセスの 3 つのうち 2 つが、独自のキーを使用しているため、無効または改ざんされているとして拒否します。
ファイルにカスタムmachineKey
を明示的に設定することで、これを回避できweb.config
ます。
または、コマンド プロンプトで再実行aspnet_regiis.exe -ga MachineName\ApplicationPoolUserName
して、壊れたアクセス許可を修正することもできます。
あなたの問題は解決しました。寝る時間です。
6 月 30 日更新: Microsoft Connectでのこの問題に関する私のレポートによると、Microsoft は、.NET 4 へのアップグレード以降、この動作が発生しないようにインストーラーを修正したことを示しています。ので、この質問/回答はそのままにしておきます。