为什么ClaimsPrincipalPermissionAttribute是密封的,还有替代方案吗?

Mat*_*int 4 c# custom-attributes claims-based-identity wif .net-4.5

我正在我的.net 4.5应用程序中实现基于声明的安全性.很多篮球跳过,但它基本上工作.

我不喜欢的唯一部分是我无法创建自己的属性.ClaimsPrincipalPermissionAttribute已被密封.为什么?

我总是在我的应用程序中标记,例如:

[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Foo", Operation = "Bar")]
Run Code Online (Sandbox Code Playgroud)

因为我希望我的资源和操作字符串不会拼写错误并且易于重构,所以我创建了类,所以我可以这样做:

[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = Resources.Foo, Operation = Operations.Foo.Bar)]
Run Code Online (Sandbox Code Playgroud)

(请注意,由于不同的资源可能具有不同的操作,因此操作本身由资源子类化.)

这一切都很好,花花公子,但每次输入或复制/粘贴都是一个很大的问题.我宁愿做类似的事情:

[DemandPermission(Resources.Foo, Operations.Foo.Bar)]
Run Code Online (Sandbox Code Playgroud)

我可以创建这个属性,但我需要从ClaimsPrincipalPermissionAttribute继承,我不能,因为它是密封的.:(

还有其他方法可以解决这个问题吗?也许我不需要继承,但我能以某种方式注册我自己的属性类型,所以它可以在所有相同的地方工作吗?

Mik*_*win 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

关于这一点需要注意的一件重要事情是,您必须在引用它的单独程序集中定义自定义属性,否则框架将抛出TypeLoadException如此处所述的

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

另外,请注意构造函数参数的默认值的使用.您需要有一个构造函数,该构造函数接受SecurityAction属性的参数以便由框架实例化.DemandPermission在这种情况下,也许是一个坏名字,因为你可以覆盖SecurityAction除了之外的东西SecurityAction.Demand.