Webアプリケーションの一部機能をSilverlightを用いる場合、Webアプリケーションのサーバとウェブブラウザ間で利用しているセッションをSilverlightに対して引き継ぐ必要があります。なぜなら、引き継がない場合、Silverlight側で再度ログインする必要があるため、ユーザビリティが低下するため。
では、どうやって引き継ぐのでしょうか?答えは簡単です。
『何もしなくてもよい!』
SilverlightからWeb(Http)アクセスをする場合、主に
・WebClient
・HttpWebRequest
・Webサービスへアクセスするための自動生成されたクラス
クラスを使用すると思いますが、デフォルトでは、全てのクラスにおいてSilverlightをホストしているウェブブラウザとセッションを共有するようです。
Webアクセスするために上記クラスを何度newしても、また別クラスをnewしても同じセッションが共有されます。
当然、Silverlightからアクセスしたサーバ側でセッションを操作した場合、Silverlightをホストしているウェブブラウザにも操作が反映されます。
要するに、SilverlightからのWebアクセスは、Silverlightをホストしているウェブブラウザを通して行われることになります。
自分は、これに気付かずに、かなりの時間悩んでしまいました。
逆に、ウェブブラウザとセッション(クッキー)を共有したくない場合、どうすればよいのでしょうか?
「WebRequest」クラスには、staticなメソッドとして、RegisterPrefix()が用意されており、この第2引数に、「System.Net.Browser.WebRequestCreator.ClientHttp」を指定します。
コード例)
IWebRequestCreate creator = System.Net.Browser.WebRequestCreator.ClientHttp;
WebRequest.RegisterPrefix("http://", creator);
WebRequest.RegisterPrefix("https://", creator);
※ほかにも方法があるかもしれませんが、自分が調べて確認できた方法は、上記方法だけでした。
上記コードを1度実行すると、その後作成する、
・WebClient
・HttpWebRequest
・Webサービスへアクセスするための自動生成されたクラス
クラスは、全てウェブブラウザとクッキーを共有しません。
また、上記クラスをnewするだけでは、新たにnewしたオブジェクト同士でもクッキーは共有されません。
オブジェクト間でクッキーを共有するためには、
オブジェクトのCookieContainerプロパティを呼び出して、同一のCookieContainerオブジェクトをセットする必要があります。
ただし、WebClientにはCookieContainerオブジェクトをセットできないのと、「Webサービスへアクセスするための自動生成されたクラス」でCookieContainerプロパティを呼び出すと例外が発生してしまい、HttpWebRequestのみまともに使用できました。
なぜ例外が発生するかまで原因を突き止めることができませんでしたm(__)m
この状態を元に戻すには、RegisterPrefix()に「System.Net.Browser.WebRequestCreator.BrowserHttp」を指定します。
問題点として、現在どちらが指定されているか取得する方法がないので、あまり想定できませんが、同一アプリケーション内で切り替えて処理を行う場合、現在どちらを指定しているかを保持するフラグを用意したほうがよいと思います。
Silverlight⇔ウェブブラウザとのセッション(クッキー)の共有方法について、まとまった資料がなかったため、今回エントリーにしました。
(デフォルトで共有されているため、当り前なのかも知れません(>_<)
最後に、今回のことを調べる上で参考にしたページを挙げておきます。
Silverlight による HTTP 通信とセキュリティ
・ClientHttpとBrowserHttpを指定した時の動作の違いが記載されています。
Silverlight:ブラウザーまたはクライアントによる HTTP 処理を指定する
Silverlight:Cookie の取得と設定を行う
