简体   繁体   English

如果应用于类,则PrincipalPermission对Method无效

[英]PrincipalPermission on Method doesn't work if applied to Class

I have code that looks something like this: 我有看起来像这样的代码:

[PrincipalPermission(SecurityAction.Demand, Role = "RoleA")]
class Foo
{
    [PrincipalPermission(SecurityAction.Demand, Role = "RoleB")]
    public static bool Bar()
    {
        return true;
    }
}

If I try to run Foo.Bar(); 如果我尝试运行Foo.Bar(); it will fail if I don't have RoleA, but never checks for RoleB. 如果我没有RoleA,但从不检查RoleB,它将失败。 It works regardless of whether or not I have RoleB, as long as I have RoleA. 只要我具有RoleA,无论我是否拥有RoleB,它都可以工作。

If I remove [PrincipalPermission(SecurityAction.Demand, Role = "RoleA")] from the class definition then it checks for RoleB as expected. 如果我从类定义中删除[PrincipalPermission(SecurityAction.Demand, Role = "RoleA")] ,则它将按预期检查RoleB。

I've searched around and found this exact problem mentioned on two different SO questions ( here and here ) with no answer in either case. 我四处搜索,发现在两个不同的SO问题( 此处此处 )中提到的确切问题,无论哪种情况都没有答案。 One has a comment that points to an old Microsoft Connect link that supposedly contains the answer, but there are no comments or answers that actually say what the problem is. 一个人的评论指向一个旧的Microsoft Connect链接,该链接应该包含答案,但没有评论或答案实际上表明问题所在。

I would really, really appreciate any help with this. 我真的非常感谢您的帮助。

Multiple PrincipalPermissionAttribute Demands are combined using OR, so in your case: 多个PrincipalPermissionAttribute需求使用OR组合,因此在您的情况下:

  • RoleA can construct an instance of the class and call any method. RoleA可以构造该类的实例并调用任何方法。
  • RoleB can call the method Bar, but can't call the constructor. RoleB可以调用方法Bar,但是不能调用构造函数。

Because of this, your code is equivalent to: 因此,您的代码等效于:

[PrincipalPermission(SecurityAction.Demand, Role = "RoleA")]
class Foo
{
    [PrincipalPermission(SecurityAction.Demand, Role = "RoleA")]
    public Foo()
    {
    }

    [PrincipalPermission(SecurityAction.Demand, Role = "RoleA")]
    [PrincipalPermission(SecurityAction.Demand, Role = "RoleB")]
    public static bool Bar()
    {
        return true;
    }
}

If you want to combine Demands using AND, you should specify Role= as a comma-separated list, eg "RoleA,RoleB". 如果要使用AND合并需求,则应将Role =指定为以逗号分隔的列表,例如“ RoleA,RoleB”。 Or use SecurityAction.Deny appropriately. 或适当使用SecurityAction.Deny。

The example below illustrates this: 下面的示例说明了这一点:

class Program
{
    static void Main(string[] args)
    {
        var aPrincipal = new GenericPrincipal(new GenericIdentity("AUser", ""), new[] {"RoleA"});
        var bPrincipal = new GenericPrincipal(new GenericIdentity("BUser", ""), new[] { "RoleB" });
        var abPrincipal = new GenericPrincipal(new GenericIdentity("ABUser", ""), new[] { "RoleB", "RoleA" });

        // AB can do anything
        Thread.CurrentPrincipal = abPrincipal;
        var sc = new SecureClass();
        TryConstruct();
        TryBMethod(sc);
        TryABMethod(sc);

        // What can A do?
        Thread.CurrentPrincipal = aPrincipal;
        TryConstruct();
        TryBMethod(sc);
        TryABMethod(sc);

        // What can B do?
        Thread.CurrentPrincipal = bPrincipal;
        TryConstruct();
        TryBMethod(sc);
        TryABMethod(sc);

        Console.WriteLine("Press ENTER to exit");
        Console.ReadLine();
    }

    static void TryConstruct()
    {
        try
        {
            var sc = new SecureClass();
        }
        catch(SecurityException)
        {
            Console.WriteLine("Constructor SecurityException for " + Thread.CurrentPrincipal.Identity.Name);
        }
    }
    static void TryBMethod(SecureClass sc)
    {
        try
        {
            sc.RoleBMethod();
        }
        catch (SecurityException)
        {
            Console.WriteLine("RoleBMethod SecurityException for " + Thread.CurrentPrincipal.Identity.Name);
        }
    }
    static void TryABMethod(SecureClass sc)
    {
        try
        {
            sc.RoleABMethod();
        }
        catch (SecurityException)
        {
            Console.WriteLine("RoleABMethod SecurityException for " + Thread.CurrentPrincipal.Identity.Name);
        }
    }

}

[PrincipalPermission(SecurityAction.Demand, Role ="RoleA")]
class SecureClass
{
    public SecureClass()
    {
        Console.WriteLine("In constructor using " + Thread.CurrentPrincipal.Identity.Name);
    }

    [PrincipalPermission(SecurityAction.Demand, Role = "RoleB")]
    public void RoleBMethod()
    {
        Console.WriteLine("In RoleBMethod using " + Thread.CurrentPrincipal.Identity.Name);
    }

    [PrincipalPermission(SecurityAction.Demand, Role = "RoleA,RoleB")]
    public void RoleABMethod()
    {
        Console.WriteLine("In RoleBMethod using " + Thread.CurrentPrincipal.Identity.Name);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM