リッチクライアントとロールベースセキュリティ (2)

Identityが認証済みかどうかの判定に関して、昨日、菊池さんにご指摘頂いた。

認証済みかはIIdentityのIsAuthenticatedを見て判断して下さい。
IIdentityのNameは「そう名乗っている」だけです。特に認証シーケンスの動作中では「そう名乗っている」だけで、認証されていないIIdentityが作られるケースが多々あります。

菊池さんの懸念とは直接関係無いのかもしれないが、サンプルをいくつか作って流していた時に、まだスレッドにPrincipalをバインドしていないにも関わらず、空のPrincipal(とIdentity)が既にバインドされているのを確認している。これは既定値でそのようになっているのだろうか。調べてみることにした。
現在のAppDomain上の全てのスレッドにバインドされているPrincipal、及び関連づけられているIdentityはね以下のプロパティで確認することができる。


Thread.CurrentPrincipal.Identity

なお、まだ何もバインドされていない状態でのPrincipalに関しては、AppDomain::SetPrincipalPolicy (PrincipalPolicy policy)というメソッドでPrincipal生成時のポリシの既定値をセットできるが、このパラメタ、PrincipalPolicyの既定値は、MSDN上では以下のように説明されている。

アプリケーション ドメインに対してプリンシパル オブジェクトと ID オブジェクトをどのように作成するかを指定します。既定値は UnauthenticatedPrincipal です。
〜 中略 〜
パフォーマンス上の理由から、既定のプリンシパル オブジェクトと ID オブジェクトは必要でない限りは作成されません。
MSDN ライブラリ - PrincipalPolicy 列挙体

説明から察するに、PrincipalPolicyの既定値はUnauthenticatedPrincipalとされているが、その後には「必要でない限りは作成されません。」とある。本当の既定値はNoPrincipalと、UnauthenticatedPrincipalのどちらだろう。
実際に確認してみると、例えばWindowsFormsアプリケーションの開始直後(FormのLoadイベント)では、Thread.CurrentPrincipal.Identityのウォッチは以下のように、既にGenericPrincaipalとGenericIdentityが生成されているのを確認できる。

恐らくは、初めて同プロパティのゲッタを実行した際に動的に生成しているのだと思われるが、MSDNの説明通り、既定値はUnauthenticatedPrincipalで間違いが無いようだ。
従って、オリジナルのPrincipalやIdentityを独自に管理したい場合には、以下のメソッドを予め実行することで、自動的に空のPrincipalとIdentityが生成されるのを抑制することができる。


Thread.GetDomain().SetPrincipalPolicy(PrincipalPolicy.NoPrincipal);