当类上有PrincipalPermission时,将忽略方法的PrincipalPermission

时间:2015-10-22 19:27:27

标签: c# .net security

我的理解一直是方法上的安全属性会覆盖类的安全属性,但下面的简单代码证明了这种情况似乎不再是这样:

class Program
{
    [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] //<-- this passes
    class DumbClass
    {
        [PrincipalPermission(SecurityAction.Demand, Role = "ffff")] //<-- this passes (but shouldn't)
        public string EchoMethod(string input)
        {
            return input;
        }
    }

    static void Main(string[] args)
    {
        Thread.CurrentPrincipal = new ClaimsPrincipal(new ClaimsIdentity("manual"));

        //this should throw becuase the principal is not in the role "ffff"
        //BUT DOESN'T
        Console.WriteLine(new DumbClass().EchoMethod("this"));
    }
}

如果我删除了类上的声明,那么我会得到预期的安全性异常。 我错过了一些非常明显的东西。我正在使用.Net 4.5

2 个答案:

答案 0 :(得分:0)

因为PrincipalPermissionAttribute Demands是使用OR组合的,并且class属性与将属性添加到每个方法基本相同,所以您的示例等效于: [PrincipalPermission(SecurityAction.Demand,Authenticated = true)] class DumbClass {     [PrincipalPermission(SecurityAction.Demand,Authenticated = true)]     public DumbClass()     {     }     [PrincipalPermission(SecurityAction.Demand,Authenticated = true)]     [PrincipalPermission(SecurityAction.Demand,Role =&#34; ffff&#34;)]     public string EchoMethod(字符串输入)     {         返回输入;     } } 由于OR逻辑,你对Role =&#34; ffff&#34;的需求是多余的。 如果要将EchoMethod限制为角色&#34; ffff&#34;,并允许所有其他方法的经过身份验证的用户,请将您的代码更改为: class DumbClass {     [PrincipalPermission(SecurityAction.Demand,Authenticated = true)]     public DumbClass()     {     }     [PrincipalPermission(SecurityAction.Demand,Role =&#34; ffff&#34;)]     public string EchoMethod(字符串输入)     {         返回输入;     }     [PrincipalPermission(SecurityAction.Demand,Authenticated = true)]     public string OtherMethod(字符串输入)     {         返回输入;     } }

答案 1 :(得分:-1)

更改您的代码:

[PrincipalPermission(SecurityAction.Demand)] //<-- REMOVE Authenticated = true
class DumbClass
{
    [PrincipalPermission(SecurityAction.Demand, Role = "ffff")] //<-- this passes (but shouldn't)
    public string EchoMethod(string input)
    {
        return input;
    }
}

通过设置Authenticated = true,您明确指出用户可能已经过验证或未验证过。