Skip to content

MS_ASPNETSession

nishi_74322014 edited this page Aug 12, 2026 · 1 revision

ASP.NET Session

概要

近年の Web アプリケーションでは

  • メモリの大容量化、
  • Session の冗長化構成対応

により、イントラネット内の業務システムでは、Session の使用は一般的になっている。

詳細

設定

Session の設定に関しては、Web.config
system.web.sessionState セクションにパラメタを設定する。

Session timeout

  • Session timeout 値の ASP.NETのデフォルトは 20(分) となっている。
  • Session は、明示的な破棄、明示的な Session timeout まで、
    メモリ上のオブジェクトが破棄されないので
    メモリリークしないように注意して利用する。

補足(Session はメモリを食う): InProc モードの Session は
w3wp.exe のメモリ上に、ユーザー数 × 保持データ分が積み上がる。

同時 1000 ユーザー × 100KB = 約 100MB(タイムアウトまで解放されない)

さらに、IISのアプリケーション プールが
リサイクル(既定 29 時間 / メモリ上限)すると全消失する。
「たまにログインし直しになる」という相談の多くはこれが原因である。
詳細はIISのパフォーマンス カウンタ
Sessions Active / Private Bytes を参照。

Session Cookie

ASP.NETのデフォルトの設定では、
Session の識別に Cookieを使用する(Cookie に SessionID を保持する)。

Session Cookieは揮発性

  • 揮発性 Cookie はプロセス内のメモリに保持されるため、
    ブラウザの別プロセスで共有することはできない。
    • このため、複数のブラウザ プロセスを起動した場合、
      揮発性 Cookie である SessionID に紐付く Session は、
      其々、別の Session として認識される。
    • 揮発性 Cookie は、ブラウザが閉じられると消失するため、
      SessionID に紐付く Session も消失する。
  • 不揮発性 Cookie(ファイルに保存できる Cookie)は、
    ブラウザの別プロセスで共有できるが、
    Session Cookie は不揮発性 Cookie に設定できない。

携帯アプリの場合

ASP.NET Mobile Web(携帯端末)の場合、
端末によっては Cookie をサポートしていないケースがあるため、
Web.configcookieless="true" を記述する。

<sessionState timeout="20" cookieless="true" mode="InProc"></sessionState>

この場合、URL に SessionID が埋め込まれる。

http://[FQDN名]/[アプリケーション名]/S(SessionID)F(認証チケット)/xxx.aspx

補足(cookieless は使ってはならない): 現在の観点では、
cookielessセキュリティ上、明確に避けるべき設定である。

問題 内容
セッション ID が URL に露出 ブラウザ履歴・Referer・プロキシ ログ・アクセス ログに残る
セッション固定攻撃 URL を送りつけるだけで攻撃が成立する
URL の共有で乗っ取り 「この URL 見て」で他人にセッションを渡してしまう

OAuth 2.0 Form Post Response Mode
述べた「URL に載せると意図しない場所に残る」という問題と同根である。
対象端末が Cookie をサポートしない、という前提自体が
現在では成り立たない。

State Service・State Database

ASP.NETでは、同一プロセスだけでなく、
別プロセス・サーバ(State Service)、
SQL Server(State Database)などに
Session 情報を保存する機能もある。

モード 保存先 特徴
InProc(既定) w3wp.exe のメモリ 速い。プロセス再起動で消える
StateServer 別プロセス(ASP.NET State Service) 再起動に耐える。シリアライズが必要
SQLServer SQL Server 永続化。最も遅いが最も堅い
Custom 任意(Redis など) 現在の主流

負荷分散(冗長化)構成とSession

障害時にも Session 情報を保持したり、クラスタ構成で
1 人のクライアントが複数のノードに振り分けられたりする場合、
別プロセス・サーバ(State Service)、
SQL Server(State Database)などに
Session 情報を保存する方式を検討する。

この場合、Session に格納するオブジェクトはシリアル化可能に実装する必要がある。

補足(NLBとの関係): NLB
ARRで負荷分散する際、選択肢は 2 つある。

方針 内容 評価
アフィニティで固定 同じユーザーを同じノードへ 簡単だがフェイル オーバーで消える・偏る
Session を外部化 State Service / DB / Redis へ 推奨。ノードが完全にステートレスになる

後者にすればノードの追加・削除・再起動が自由になり、
クラウドのオートスケールとも噛み合う。
NLBクラウド設計パターン
記述とも一貫する結論である。

補足(ASP.NET Coreの Session は別物): 移行時に
大きく変わる箇所なので整理しておく。

ASP.NET ASP.NET Core
既定 有効InProc 無効(明示的に AddSession()
格納できる型 任意のオブジェクト(シリアライズ可能なら) byte[] / string / int のみ
複雑な型 そのまま入る 自分で JSON 等にシリアライズする
分散ストア State Service / SQL Server IDistributedCache(Redis / SQL Server)
builder.Services.AddStackExchangeRedisCache(o =>
    o.Configuration = "redis:6379");
builder.Services.AddSession();
// ...
HttpContext.Session.SetString("user", JsonSerializer.Serialize(user));

Session["key"] = obj がそのまま動かない」というのが
ASP.NET Coreへの移行での定番の詰まりどころである。

より根本的には、Session を使わずトークン(JWT)で
ステートレスにする
設計も検討したい。

参考

Microsoft Learn


Tags: 移行, .NET開発, ASP.NET, ASP.NET Web Forms, ASP.NET MVC

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally