書籍転載
|
|
|
■7.3 セッション情報
前節では、ページ間で情報を共有するための仕掛けとして、クッキーを取り上げました。しかし、クッキーにはいくつかの問題点があります。
○[問題]データがクライアント側で保存される
前節でも述べたように、クッキーはクライアント側で管理されるデータです。クライアント(ブラウザー)の設定によってはそもそもクッキーを受け入れないようにすることも可能ですし、いったん保存されたクッキーをクライアント側で改ざんしたり削除したりすることもできます。そのため、クッキーによって得られたデータをもとに処理を制御するのは、時として危険が伴う場合があります。
○[問題]実データがネットワーク上を流れる
図7.5でも見たように、クッキーはネットワーク上で受け渡しされます。つまり、通信経路にリクエスト情報をロギングするような通信機器やソフトウェアがあったとしたら、意図するとせざるとにかかわらず、クッキーの内容が漏えい(盗聴)されてしまう可能性があります。
セキュリティが取りざたされる昨今の情勢を考えれば、このような状態はセキュリティホールの一因となる場合もあり、好ましいことではありません。そこで、ユーザーがブラウザーを開いている間だけ情報を維持したいという場合には、クッキーではなく、セッション(Session)という仕組みを利用するようにすべきです。セッションは、何日、何週間という単位で情報を保持するような用途には不向きですが、アプリケーション内で情報を受け渡ししたいという場合には、クッキーよりも手軽に、かつ、セキュアに扱うことができます。
●7.3.1 セッション機能の基本
まずはセッションの仕組みについて見てみることにしましょう(図7.8)。
図7.8 クッキーとセッション |
まず理解していただきたいのは、セッション情報そのものはあくまでサーバーサイドで管理されるものであり、クライアント/サーバー間でやりとりされるのは、そのキーだけであるという点です。そして、クライアント単位に発行されるキーとなるのが、セッションIDです。サーバーサイドでは、クライアントから発信されたセッションIDをキーにして、セッション情報にアクセスできます。
これによって、セッションでは「データがユーザーに改ざん/削除されてしまう」「データを盗聴されやすい」という、クッキーの問題点を解消しているのです。
セッション情報の取得/設定は、クッキーよりも簡単です(リスト7.4〜5)。
|
|
リスト7.4 Session1.aspx.vb |
|
|
リスト7.5 Session2.aspx.vb |
Session1.aspxを実行した後、ブラウザーを閉じずにそのままSession2.aspxにアクセスしてください。確かにSession1.aspxでセットされたアプリケーション変数が、Session2.aspxでも見えていることが確認できるはずです。クッキーとは異なり、セッションはあくまでブラウザーが開いている間のみ情報を保持するための機能なので、ブラウザーを閉じてしまうと、セッションもクリアされます。
セッションを読み書きするのは、Sessionオブジェクトの役割です。
|
|
構文 セッションの取得/設定 |
取得に際しては、値がまだセットされていない場合も想定して、必ずNothingであるかどうかのチェックを忘れないようにしてください。
また、既存のセッションを削除するには、Remove/RemoveAll/Abandonメソッドを利用します。Removeメソッドは指定された特定のセッション情報を、RemoveAllメソッドは現在保持されているセッション情報すべてを、そして、Abandonメソッドは、セッションそのもの(情報だけではなく、セッション情報のキーであるセッションIDを含む)を破棄します。
Session.Remove("hogehoge") 'セッション情報"hogehoge"を削除
Session.RemoveAll() 'すべてのセッション情報を削除
Session.Abandon() 'セッションそのものを削除
前述したように、セッション情報はサーバー上に保持されるものです。サーバー上のリソースを節約するという意味からも、セッション情報は、不要になったできるだけ早いタイミングで破棄すべきでしょう。
【エキスパートに訊く】 セキュリティ保全のためにはセッション機能を利用するべきであるということでした。でも、セッションを使えばセキュリティは絶対に安全なのでしょうか? |
いえ、そのようなことはありません。セッションでも、セキュリティIDがネットワーク上を流れる以上、これを盗聴されてしまえば、いわゆる「なりすまし」も可能です。しかし、そもそもセッションID自体が一時的に生成されるキーですので、リアルタイムで盗聴を行っていない限り、なりすましを行うのは難しいと言えます。 ここでセッションが安全と言っているのは、あくまで「データが直接ネットワーク上を行き来するクッキーよりも相対的に」という程度の意味です。 |
●7.3.2 <sessionState>要素の主な属性
セッションの基本的な仕組み、利用方法が理解できたところで、セッションの保存/授受方法など基本的な設定をアプリケーション構成ファイル上でカスタマイズする方法について紹介しましょう。セッションの挙動を表すのは、<sessionState>要素の役割です。
以下に、sessionState要素で利用できる主な属性をまとめます。
mode属性
セッションの格納先を設定します。表7.5のような値を設定できます。
設定値 | 概要 |
Off | セッションが無効 |
InProc | ローカルのメモリ上に格納 |
StateServer | 専用のState Serviceに格納 |
SQLServer | SQL Serverに格納 |
Custom | カスタムのデータストアに格納 |
表7.5 mode属性の設定値 |
InProc(インプロセスモード)は、サーバーのメモリにセッションを保存するモードで、最も高速に動作します。しかし、サーバーをクラスター構成にした場合、セッションを共有できない、アプリケーションの再起動時にセッションがクリアされてしまう、などの制約もあります。
本番環境でセッションを利用する場合には、State Server、SQL Serverなどのモードを優先して利用することをおすすめします。これらのモードは、インプロセスモードよりも低速ですが、その分、確実にセッションを維持できます。
* Webアプリケーションの再起動は次のような場合に発生します。
|
timeout属性
セッションのタイムアウト時間(デフォルトは20分)を設定します。
パフォーマンス、セキュリティ双方の側面から、timeout属性にはアプリケーションごとに適切な値を設定すべきです。不要になったセッションがサーバー上に残り続けることは、サーバーリソースの浪費だけでなく、悪意ある第三者(クラッカー)に対してセッション盗聴の機会を与えることでもあるからです。
ただ、無条件にタイムアウト時間を短くしてやればそれで良いというものではありません。ユーザーが長時間に渡って放置する可能性があるグループウェアのようなアプリケーションでは、長めにタイムアウト時間を確保する必要があるかもしれませんし、厳密なセキュリティを要求されるアプリケーションでは短めに設定すべきです。大量のセッションデータを保持するようなアプリケーションやメモリリソースが逼迫しているようなサーバー環境でもタイムアウト時間を短めに設定してやらなければならないかもしれません。タイムアウト時間とは、その時どきの用途/環境の制約に応じて「あなたが」チューニングすべき項目です。
* セッションの性質上、やや誤解を招きやすいのですが、セッション情報はブラウザーを閉じた時点ではまだ破棄されていません。ブラウザーを閉じた時点で削除されるのは、セッション情報を紐づけるためにブラウザーに保存されたセッションIDだけであり、これによって、クライアント側からは見かけ上、セッションが破棄されたように見えるわけです。しかし、サーバー側で保持されたセッション情報は、この時点では依然として生き続けています。サーバー側のセッション情報を破棄するには、Abandonなどのメソッドを明示的に呼び出すか、セッションの有効期限を経過しなければなりません。 |
commpressionEnabled属性
セッション情報を圧縮します。特に、セッション情報を外部プロセスに保存する場合には、圧縮機能を有効にし、データサイズを最小限に抑えることをおすすめします。ASP.NET 4から導入された新機能です。
cookieless属性
セッションIDをクッキー、URL埋め込みのいずれで受け渡すかを設定します(表7.6)。
設定値 | 概要 |
AutoDetect | ブラウザーのクッキーサポート、有効無効をチェックし、その結果によってクッキー、URL埋め込みのいずれかを選択的に利用 |
UseCookies | 常にクッキーを使用 |
UseDeviceProfile | ブラウザーのプロファイル情報によってクッキー、URL埋め込みのいずれかを選択的に決定 |
UseUri | 無条件にクエリ文字列を使用 |
表7.6 cookieless属性の設定値 |
AutoDetect/UseDeviceProfileモードでは、ブラウザーがクッキーをサポートしていない場合にURL経由でセッションIDを受け渡ししようとします。これには、以下のようなURLが用いられます。
http://localhost:81/(S(m0i5pggddoymmw0sbnqcybce))/Chap07/Session1.aspx
しかし、これはセッションIDがまるまる露出してしまうという点で、セキュリティ的には好ましくありません(クッキーであれば絶対に安全という意味ではありません)。クッキーレス対応は、クッキー未対応のブラウザーでセッションを利用する場合に留めるようにしてください。そうした意味で、UseUriモードはテスト目的の場合を除いては利用するべきではありません。
* そもそもAJAX対応のアプリケーションを実装している場合、URL埋め込みのセッションは利用できません。 |
●7.3.3 セッションの外部プロセス管理
パフォーマンス上のデメリットこそあるものの、外部プロセスでセッションを管理することで、セッション情報をより確実に維持できるというメリットがあります。本番環境でのセッション管理には、できるだけ外部プロセスによる管理を選択することをおすすめします。
以下では、外部プロセス管理の1つとして、State Service(ASP.NET状態サービス)によるセッション管理の方法を解説します。インプロセスモードと同じく、メモリ上でセッション情報を管理しますが、アプリケーションとは別のプロセス(サービス)で動作するという点が異なります。後述するSQL Serverモードよりは高速ですが、State Serviceを再起動すると、やはりセッション情報は破棄されてしまいますので、注意してください。
○1.State Serviceを起動する
State Serviceは、コントロールパネルの[システムとセキュリティ]→[管理ツール]→[サービス]から起動できます。[ASP.NET状態サービス]を右クリックし、コンテキストメニューから[開始]を選択します(図7.9)。
図7.9 State Serviceの起動 |
* プロパティシートから[スタートアップの種類]を[自動]とすることで、サーバー起動時に自動起動させることもできます。 |
○2.State Serviceを有効化する
State Serviceによるセッション管理を有効にするには、アプリケーション構成ファイルにリスト7.6のような記述を追加します(記述位置は<system.web>要素の直下であればどこでもかまいません)。
|
|
リスト7.6 Web.config |
以上でState Serviceを使用する設定は完了です。これで、セッションデータはState Serviceのプロセス上に保存されるようになりました。<sessionState>要素のstateConnectionString属性には、今回はローカルアドレス(127.0.0.1)を指定していますが、一般的にはState Serviceが稼働しているサーバーのIPアドレスを指定します。
●7.3.4 セッションのSQL Server管理
ただし、State Serviceでも、セッション情報はメモリに保存されます。つまり、サーバーの再起動によって、セッションがクリアされてしまう点は、インプロセスモードと変わりありません(アプリケーションと分離されている分、安全というだけです)。セッション情報をより確実に維持するという意味では、SQL Serverモードを利用するのが望ましいでしょう。
○1.SQL Serverにセッションデータベースを生成する
SQL Serverをセッションの保存先として使用する場合には、あらかじめ.NET Frameworkのインストールフォルダーに用意されたaspnet_regsqlを利用して、セッション管理用のデータベースをSQL Serverに展開しておく必要があります。
aspnet_regsqlは「<システムルート>¥Microsoft.NET¥Framework¥<バージョン番号>」に保存されていますので、コマンドプロンプトから以下のように実行してください。
> cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
> aspnet_regsql -S .\SQLEXPRESS -E -ssadd -sstype p
それぞれのオプションの意味は、表7.7のとおりです。
オプション | 概要 |
-S server | 接続先のSQL Serverのコンピューター名 |
-EWindows | 認証を有効化 |
-ssadd | セッションデータベースを作成 |
-sstype type | 作成するデータベースの種類 |
表7.7 aspnet_regsqlコマンドの実行オプション |
-sstypeオプションには、セッションデータベースを永続的なデータベース(p:ASPStateデータベース)に作成するか、一時的なデータベース(t:tempdbデータベース)に作成するかを指定します。ただし、tempdbデータベースではSQL Serverを再起動するたびに、セッション情報はクリアされてしまいますので、要注意です。
○2.セッションデータベースを確認する
VWDのデータベースエクスプローラー(サーバーエクスプローラー)からデータベースの内容を確認しておきましょう。[データ接続]を右クリックし、コンテキストメニューから[接続の追加...]を選択します(図7.10)。
図7.10 ASPStateデータベースへの接続設定 |
セッション格納/操作のためのテーブルやストアドプロシージャが、ASPStateデータベースに作成できていることが確認できます(図7.11)。ASPStateTempApplicationsテーブルは現在「SQL Serverセッション」を利用しているアプリケーションを、ASPStateTempSessionsテーブルはセッションに関する一連の構成情報(ID、作成時間、有効期限、タイムアウト期限、データ本体)をそれぞれ格納するテーブルです。
図7.11 ASPStateデータベースの内容 |
○3.SQL Serverを有効化する
Web.configにリスト7.7のように記述します(記述位置は<system.web>要素の直下であればどこでもかまいません)。
|
|
リスト7.7 Web.config |
sqlConnectionString属性には、セッションデータベースに接続するための接続文字列を指定します。
以上で、SQL Serverを使用する設定は完了です。これで、セッションデータはSQL Serverのテーブルに保存されるようになります。
【練習問題】7.2 |
|
■
引き続き次回は、「第7章 状態管理」から「7.4 アプリケーション変数/7.5 キャッシュ機能」を転載します。
INDEX | ||
[書籍転載]独習ASP.NET 第3版 | ||
ASP.NETの状態管理:ビューステート/クッキー/セッション情報 | ||
1.ビューステート | ||
2.クッキー | ||
3.セッション情報 | ||
「独習ASP.NET 第3版」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|