ASP.NET でセッション ID が再利用されるしくみと理由について

文書翻訳 文書翻訳
文書番号: 899918 - 対象製品
すべて展開する | すべて折りたたむ

はじめに

この資料では、Microsoft ASP.NET のセッション ID が使用されるしくみと理由について説明します。

詳細

ASP.NET のセッション状態は、サーバー側から見たユーザー固有のデータの保持を可能にする技術です。Web アプリケーションは、このデータを使用して、セッション状態のインスタンスが生成されている、ユーザーからの要求を処理できます。セッション状態のユーザーは、セッション ID で識別されます。セッション ID は、次のいずれかの方法を使用して配布されます。
  • セッション ID をユーザーのブラウザーに送信される Cookie の一部に含めます。
  • セッション ID を URL に埋め込みます。この技法は、"Cookie のないセッション" としても知られています。
セッション ID は、20 文字の文字列で表される 120 ビットの乱数値です。この文字列は、URL に含めることができ、URL エンコーディングを行う必要のない形式に設定されます。たとえば、この文字列は Cookie のないセッションで使用できます。最も一般に使用されるセッション ID 配布方法は、セッション ID を格納した Cookie を使用することです。

ユーザーが最初に Web ブラウザーを開き、ASP.NET のセッション状態を実装した Web サイトにアクセスすると、20 文字の値を持つ "ASP.NET_SessionId" という名前の Cookie がブラウザーに送信されます。

ユーザーが同じ DNS ドメイン内で閲覧するときに、Web ブラウザーは、この Cookie をその元になったドメインに送信し続けます。

たとえば、app1.tailspintoys.com と app2.tailspintoys.com の両方が ASP.NET アプリケーションだとします。ユーザーが app1.tailspintoys.com にアクセスした後、app2.tailspintoys.com にアクセスした場合、両方のアプリケーションが同じ Cookie と同じセッション ID を使用して、それぞれのアプリケーション内でユーザーのセッション状態を追跡します。これらのアプリケーションが、同じセッション状態を共有することはありません。アプリケーションが共有するのは、セッション ID のみです。

このため、いくつかの理由でセッション ID を再利用できます。たとえば、セッション ID を再利用すれば、以下の操作を行う必要がなくなります。
  • 有効なセッション ID が渡されているときに、暗号化された一意のセッション ID を新しく作成する
  • 単一のドメインにある各 ASP.NET アプリケーション用に新しいセッション ID を作成する
Web アプリケーションがログオンを要求し、ログオフのページやオプションを提供する場合は、ユーザーが Web サイトからログオフしたときにセッション状態を消去することをお勧めします。セッション状態を消去するには、Session.Abandon メソッドを呼び出します。Session.Abandon メソッドを使用すると、セッション状態がタイムアウトになるのを待たずに、セッション状態を除去できます。既定では、このタイムアウトは 20 分のスライド式有効期限になっています。この有効期限は、ユーザーから Web サイトへの要求が行われ、セッション ID の Cookie を提供するたびに更新されます。Abandon メソッドは、セッション状態を破棄する必要があることを示すフラグをセッション状態オブジェクトに設定します。ページ要求の最後にこのフラグが調べられ、それに基づいて処理が行われます。このため、ユーザーは Abandon メソッドを呼び出した後にページ内でセッション オブジェクトを使用できます。ページ処理が完了するとすぐに、セッションは削除されます。

インプロセス セッション状態モードを使用する場合、これらのセッション状態オブジェクトは HttpCache に格納されます。HttpCache は、次の条件に該当する場合のコールバック メソッドをサポートしています。
  • キャッシュ エントリが削除されたとき
  • セッション状態マネージャーが、キャッシュ エントリが削除されると呼び出される Session_OnEnd イベント ハンドラーを登録したとき
セッション状態マネージャーがキャッシュに存在するセッション状態オブジェクトを削除すると、HttpCache マネージャーによって、登録済みのあらゆるコールバックが呼び出されます。結果として、この動作で Session_OnEnd イベント ハンドラーが呼び出されます。

セッションを破棄しても、セッション ID の Cookie はユーザーのブラウザーから削除されません。このため、セッションが破棄されると、同じアプリケーションに対する新しい要求は同じセッション ID を使用しますが、新しいセッション状態インスタンスが用意されます。同時に、同じ DNS ドメイン内の別のアプリケーションをユーザーが開いた場合、1 つのアプリケーションから Abandon メソッドが呼び出された後にユーザーがセッション状態を失うことはありません。

ときには、セッション ID の再利用を避けたい場合もあり得ます。セッション ID を再利用しないことの影響を理解している場合は、次のコード例を使用して、セッションの破棄とセッション ID の Cookie の消去を行ってください。
Session.Abandon();Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
このコード例は、サーバーからセッション状態を消去し、セッション状態 Cookie を null に設定します。null 値により、実際にブラウザーから Cookie が消去されます。

ユーザーがアプリケーションからログオフせず、セッション状態のタイムアウトが発生した場合でも、ユーザーがブラウザーを閉じなければ、アプリケーションは引き続き同じセッション状態 Cookie を使用できます。この動作により、ユーザーにはログオン ページが表示され、そのユーザーのセッション状態 Cookie が提供されます。ログオン ページ (login.aspx) を開いたときに必ず、新しいセッション ID が使用されるようにするには、null の Cookie をクライアントに返送します。これを行うには、Cookie を 1 つ、応答のコレクションに追加した後、このコレクションをクライアントに返送します。null の Cookie を送信する最も簡単な方法は、Response.Redirect メソッドを使用することです。Cookie のコレクションは常に ASP.NET_SessionId の値を持っているため、Cookie が存在するかどうかを単にテストすることはできません。これは、Response.Redirect ループを作成することになるためです。ログオン ページへのリダイレクトの際に、クエリ文字列を設定できます。

あるいは、次のコード例に示すように、別の Cookie を使用して、ログオン ページに既にリダイレクトされているかどうかを確認できます。セキュリティを強化し、誰も ASP.NET の Cookie と共に第 2 の Cookie を使用してログオン ページを開くことができないよう、次のコード例では FormsAuthentication クラスを使用して、Cookie データの暗号化と暗号化解除を行った後、5 秒のタイムアウトを設定します。
private void Page_Load(object sender, System.EventArgs e)
{ 
if( !IsPostBack && 
( Request.Cookies["__LOGINCOOKIE__"] == null ||
Request.Cookies["__LOGINCOOKIE__"].Value == "" ) )
{
//この時点では、使用するセッション ID が新しいセッション ID か
//セッション ID がクライアントによって渡されたかどうかわからない。 
//セッション ID を更新する。

Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));

//クライアントがセッション ID Cookie をクリアすることを確認するには、クライアントに応答して、 
//応答したことを知らせる。これを行うには別の Cookie を設定する。
AddRedirCookie();
Response.Redirect( Request.Path );
}

//誰かがスプーフィングしようとしていないことを確認する。
try
{
FormsAuthenticationTicket ticket =
FormsAuthentication.Decrypt( Request.Cookies["__LOGINCOOKIE__"].Value );

if( ticket == null || ticket.Expired == true ) 
throw new Exception();

RemoveRedirCookie();
}
catch
{
//誰かがスプーフィングしようとしている場合は、もう一度実行する。
AddRedirCookie();
Response.Redirect( Request.Path );
}


Response.Write("Session.SessionID="+Session.SessionID+"<br/>");
Response.Write("Cookie ASP.NET_SessionId="+Request.Cookies["ASP.NET_SessionId"].Value+"<br/>");
} 

private void RemoveRedirCookie() 
{ 
Response.Cookies.Add(new HttpCookie("__LOGINCOOKIE__", "")); 
} 

private void AddRedirCookie()
{

FormsAuthenticationTicket ticket = 
new FormsAuthenticationTicket(1,"Test",DateTime.Now,DateTime.Now.AddSeconds(5), false,""); 
string encryptedText = FormsAuthentication.Encrypt( ticket ); 
Response.Cookies.Add( new HttpCookie( "__LOGINCOOKIE__", encryptedText ) );
}
注意 : これは、マイクロソフトのサポート組織内で直接作成された "緊急公開" の資料です。 この資料には、確認中の問題に関する現状ベースの情報が記載されています。 情報提供のスピードを優先するため、資料には誤植が含まれる可能性があり、予告なしに随時改定される場合があります。 その他の考慮事項については、使用条件を参照してください。

プロパティ

文書番号: 899918 - 最終更新日: 2013年7月2日 - リビジョン: 1.0
この資料は以下の製品について記述したものです。
  • Microsoft .NET Framework 1.1
キーワード:?
kbinfo kbhowto KB899918
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com