-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ASPNETSession
- 戻る(ASP.NETの状態管理方式)
- ASP.NET Session
- ASP.NET / ASP.NET Core
- Cookie
近年の Web アプリケーションでは
- メモリの大容量化、
- Session の冗長化構成対応
により、イントラネット内の業務システムでは、Session の使用は一般的になっている。
Session の設定に関しては、Web.configの
system.web.sessionState セクションにパラメタを設定する。
- Session timeout 値の ASP.NETのデフォルトは 20(分) となっている。
- Session は、明示的な破棄、明示的な Session timeout まで、
メモリ上のオブジェクトが破棄されないので
メモリリークしないように注意して利用する。
補足(Session はメモリを食う):
InProcモードの Session は
w3wp.exeのメモリ上に、ユーザー数 × 保持データ分が積み上がる。同時 1000 ユーザー × 100KB = 約 100MB(タイムアウトまで解放されない)さらに、IISのアプリケーション プールが
リサイクル(既定 29 時間 / メモリ上限)すると全消失する。
「たまにログインし直しになる」という相談の多くはこれが原因である。
詳細はIISのパフォーマンス カウンタの
Sessions Active/Private Bytesを参照。
ASP.NETのデフォルトの設定では、
Session の識別に Cookieを使用する(Cookie に SessionID を保持する)。
- 揮発性 Cookie はプロセス内のメモリに保持されるため、
ブラウザの別プロセスで共有することはできない。- このため、複数のブラウザ プロセスを起動した場合、
揮発性 Cookie である SessionID に紐付く Session は、
其々、別の Session として認識される。 - 揮発性 Cookie は、ブラウザが閉じられると消失するため、
SessionID に紐付く Session も消失する。
- このため、複数のブラウザ プロセスを起動した場合、
- 不揮発性 Cookie(ファイルに保存できる Cookie)は、
ブラウザの別プロセスで共有できるが、
Session Cookie は不揮発性 Cookie に設定できない。
ASP.NET Mobile Web(携帯端末)の場合、
端末によっては Cookie をサポートしていないケースがあるため、
Web.configに cookieless="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 をサポートしない、という前提自体が
現在では成り立たない。
ASP.NETでは、同一プロセスだけでなく、
別プロセス・サーバ(State Service)、
SQL Server(State Database)などに
Session 情報を保存する機能もある。
| モード | 保存先 | 特徴 |
|---|---|---|
InProc(既定) |
w3wp.exe のメモリ |
速い。プロセス再起動で消える |
StateServer |
別プロセス(ASP.NET State Service) | 再起動に耐える。シリアライズが必要 |
SQLServer |
SQL Server | 永続化。最も遅いが最も堅い |
Custom |
任意(Redis など) | 現在の主流 |
障害時にも 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)で
ステートレスにする設計も検討したい。
- ASP.NET でSessionCookie、Cookie認証Ticketを共有する方法
(ASP.NET でSessionCookie、Cookie認証Ticketを共有する方法)
-
ASP.NET セッション状態の概要
https://learn.microsoft.com/previous-versions/aspnet/ms178581(v=vs.100) -
ASP.NET Core のセッションと状態管理
https://learn.microsoft.com/aspnet/core/fundamentals/app-state
Tags: 移行, .NET開発, ASP.NET, ASP.NET Web Forms, ASP.NET MVC
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。