4

.net 4.5 アプリケーションにクレーム ベースのセキュリティを実装しています。ジャンプするフープがたくさんありますが、基本的には機能しています。

私が気に入らない唯一の部分は、独自の属性を作成できないことです。ClaimsPrincipalPermissionAttribute は封印されています。なんで?

私は常にアプリケーション全体で次のようにマークしています。

[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Foo", Operation = "Bar")]

また、リソースと操作の文字列のつづりを間違えないようにし、簡単にリファクタリングできるようにしたいので、これを実行できるようにクラスを作成しました。

[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = Resources.Foo, Operation = Operations.Foo.Bar)]

(リソースによって操作が異なる場合があるため、操作自体はリソースによってサブクラス化されることに注意してください。)

これはすべてうまく機能しますが、毎回入力したり、コピー/貼り付けしたりするのは大変です。私はむしろ次のようなことをしたい:

[DemandPermission(Resources.Foo, Operations.Foo.Bar)]

この属性を作成することはできますが、ClaimsPrincipalPermissionAttribute から継承する必要がありますが、シールされているため作成できません。:(

これにアプローチする他の方法はありますか?おそらく継承する必要はありませんが、独自の属性タイプを登録して、すべて同じ場所で機能するようにすることはできますか?

4

3 に答える 3

7

ClaimsPrincipalPermissionAttributeから派生しCodeAccessSecurityAttributeます。渡した Resource と Operation の値に基づいてCreatePermission()new を返す実装を除いて、ほとんど何もしません。ClaimsPrincipalPermission

から派生した新しいクラスCodeAccessSecurityAttribute(これは封印されていません) を実装して、必要なことを行うことができます。

JustDecompile を使用すると、コードClaimsPrincipalPermissionAttributeが単純であることがわかります。次のように独自の属性を作成できます。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public sealed class DemandPermissionAttribute : CodeAccessSecurityAttribute
{
    public Operations Operation { get; set; }
    public Resources Resource { get; set; }

    public DemandPermissionAttribute(SecurityAction action = SecurityAction.Demand)
        : base(action)
    {
    }

    public override IPermission CreatePermission()
    {
        return new ClaimsPrincipalPermission(this.Resource.ToString(), this.Operation.ToString());
    }
}

これについて注意すべき重要な点の 1 つは、参照しているアセンブリとは別のアセンブリでカスタム属性を定義する必要があることです。そうしないと、フレームワークはTypeLoadExceptionここで説明されているように

http://msdn.microsoft.com/en-us/library/vstudio/yaah0wb2.aspx

また、コンストラクタ パラメータのデフォルト値の使用にも注意してください。SecurityActionフレームワークによってインスタンス化される属性のパラメーターを受け取るコンストラクターが必要です。をオーバーライドして 以外のDemandPermission名前にすることができるため、この場合はおそらく悪い名前です。SecurityActionSecurityAction.Demand

于 2013-11-01T16:41:19.740 に答える
3

ClaimsPrincipalPermissionAttribute は封印されています。なんで?

Eric Lippertは、フレームワーク型でのシールの共通性について話しました。コード セキュリティについて話しているので、このビットは非常に重要です。

封印されていない型のインスタンスを取るメソッドを実装するたびに、その型の潜在的に敵対的なインスタンスに直面しても堅牢になるようにそのメソッドを作成する必要があります。一部の敵対的な Web ページが実装をサブクラス化し、仮想メソッドをオーバーライドしてロジックを台無しにする処理を実行し、それを渡す可能性があるため、実装の真であることがわかっている不変条件に依存することはできません。 クラスを封印するたびに、そのクラスが何をするかを知っているという自信を持って、そのクラスを使用するメソッドを書くことができます。

この場合、これはさらに重要であり、インターフェースClaimsPrincipalPermissionAttributeを介してチェックされIClaimsPrincipalます。したがって、ClaimsPrincipalPermissionAttributeシールを作成することにより、実装者はIClaimsPrincipal敵対的な実装について心配する必要がなくなります。これはすべてセキュリティ関連であるため、かなりの節約になります。

于 2012-08-28T17:42:09.443 に答える
1

私の即座の反応は、それを書くのはそれほど多くないということです - そして、どれくらいの頻度でそれを書く必要がありますか? コントローラーのアクションに一般的な場合は、コントローラーに配置します。多くのコントローラーに適用できる場合は、その属性で ControllerBase を作成します。

あなたのケースがそれよりも特別な場合は、その属性の独自のさまざまな実装を余儀なくされていると思います.

于 2012-08-28T17:28:04.007 に答える