これを実行できる場所はいくつかありますが、を使用している場合SessionAuthenticationModule
は、プロセスの一部が十分に文書化されていないため、カスタムプリンシパルの使用が難しくなる可能性があります。この回答の残りの部分では、を使用するときにこれを処理する1つの可能な方法について説明しSessionAuthenticationModule
ます。
メソッドをオーバーライドしSessionAuthenticationModule.SetPrincipalFromSessionToken
ます。
SessionAuthenticationModuleは、セキュリティトークン、プリンシパル、ID、およびクレームをCookieとメモリ内キャッシュに格納して、要求ごとにIDプロバイダー/トークンサービスにラウンドトリップする必要をなくします。十分に文書化されていないのは、キャッシュの存在と、それが最初にチェックされ、次にCookieであり、シリアル化の制限であるということClaimsPrincipal
です。
すでにカスタムプリンシパルを設定していてClaimsAuthenticationManager.Authenticate
、キャッシュがそのままの場合、キャッシュにはネイティブ.NETオブジェクトが格納されるため、カスタムプリンシパルはすでに存在している可能性があります。カスタムプリンシパルをまだ設定していない場合、またはキャッシュにデータが入力されていない場合、セキュリティトークンはFedAuthセッションCookieから取得されます。
トークンがCookieとの間でシリアル化/逆シリアル化される場合、プロセスは、IClaimsPrincipal
およびIClaimsIdentity
インターフェイス(またはClaimsPrinicpal
およびClaimsIdentity
クラス-どちらかを思い出せません)の属性の読み取りと書き込みのみが可能なカスタムシリアル化を使用します。カスタムプリンシパルおよびIDオブジェクト属性は含まれません。シリアル化をオーバーライドすることは可能かもしれませんが、それにはクラスオーバーライドのいくつか(3 IIRC)以上のレイヤーが必要です。
SetPrincipalFromSessionToken
また、baseメソッドが新しいClaimsPrincipal
オブジェクトを作成し、それをスレッドとコンテキストに設定するという事実にも注意する必要があります。そのため、sessionSecurityToken
パラメーターにカスタムプリンシパルオブジェクトが含まれている場合でも、オブジェクトに変換されClaimsPrincipal
ます。
オーバーライドメソッドの例を次に示します。
protected override void SetPrincipalFromSessionToken(SessionSecurityToken sessionSecurityToken)
{
SessionSecurityToken newToken = MyClaimsPrincipalUtility.CreateCustomClaimsPrincipalToken(sessionSecurityToken);
base.SetPrincipalFromSessionToken(newToken);
//the following lines need to be set after the base method call, because the base method overwrites the Principal object
HttpContext.Current.User = newToken.ClaimsPrincipal;
Thread.CurrentPrincipal = newToken.ClaimsPrincipal;
}
基本クラス(SessionAuthenticationModule
)の実装は次のようになります。したがって、カスタムクレームプリンシパルをオーバーライドして取得する方法はいくつかあります。
protected virtual void SetPrincipalFromSessionToken(SessionSecurityToken sessionSecurityToken)
{
IClaimsPrincipal fromIdentities = ClaimsPrincipal.CreateFromIdentities(this.ValidateSessionToken(sessionSecurityToken));
HttpContext.Current.User = (IPrincipal) fromIdentities;
Thread.CurrentPrincipal = (IPrincipal) fromIdentities;
//tracing code removed
this.ContextSessionSecurityToken = sessionSecurityToken;
}
念のために言っておきますが、これがの基本クラスの実装ですSessionAuthenticationModule.ContextSessionSecurityToken
。
public virtual SessionSecurityToken ContextSessionSecurityToken
{
get
{
return (SessionSecurityToken) HttpContext.Current.Items[(object) typeof (SessionSecurityToken).AssemblyQualifiedName];
}
internal set
{
HttpContext.Current.Items[(object) typeof (SessionSecurityToken).AssemblyQualifiedName] = (object) value;
}
}