4

私は、フォームベースの認証とクレームベースの認証の両方を使用するWebサイト(ASP.NET C#を使用)に取り組んでいます。カスタムIsAuthenticatedメソッドを実装し、クレーム認証に固有のIDにさらにプロパティを追加できるように、ClaimsIdentityクラスをオーバーライドしたかったのです。

現在、カスタムWSFederationAuthentionModuleを実装していますが、デフォルトのClaimsPrincipalではなくカスタムID /プリンシパルを設定できるように、オーバーライドする必要のあるモジュール(具体的にはどのメソッド)を見つけようとしていましたか?

これまで、SessionAuthenticationModuleとClaimsPrincipalHTTPModuleの両方を見てきましたが、プリンシパルが設定されているステップ/それをオーバーライドするための最良の方法を理解できませんでした。

ありがとう

追加: 私はこれに少し慣れていないので、これが正しいことを確認させてください:IDを設定する方法は、そのIDを使用するように設定されたカスタムプリンシパルを設定することです。

System.Threading.Thread.CurrentPrincipal = customClaimsPrincipal;

または、カスタムプリンシパルが不要な場合は、ClaimPrincipalクラスをClaimsIdentityCollectionを使用して構築できます。

4

2 に答える 2

3

これを実行できる場所はいくつかありますが、を使用している場合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;
    }
}
于 2013-10-17T21:24:43.910 に答える
1

HttpModulesが拡張性の観点からは正しい方法ですが、実装するロジックがアプリケーションのパフォーマンスを妨げないようにしてください。アプリケーションにHttpModuleを追加しすぎた後、Webサイトのパフォーマンスが大幅に低下しました。使用している認証モデルによっては、クエリの結果をキャッシュする価値がある場合があります。

カスタムClaimsPrincipalを使用するために必要な条件を把握する必要があります。あなたがこれをするまで、あなたは暗闇の中で刺している。クレーム認証が必要な特定のURLはありますか?

于 2012-03-20T12:33:53.100 に答える