PrincipalPermission для методов игнорируется, когда есть PrincipalPermission для класса

Я всегда понимал, что атрибуты безопасности в методах переопределяют атрибуты безопасности в классе, но, похоже, это уже не так, как показывает простой код, приведенный ниже:

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 ответа

Так как PrincipalPermissionAttribute Требования объединяются с использованием ИЛИ, а атрибут класса по сути такой же, как и добавление атрибута к каждому методу, ваш пример эквивалентен:

[PrincipalPermission(SecurityAction.Demand, Authenticated = true)] 
class DumbClass
{
    [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] 
    public DumbClass()
    {
    }

    [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] 
    [PrincipalPermission(SecurityAction.Demand, Role = "ffff")]
    public string EchoMethod(string input)
    {
        return input;
    }
}

и из-за логики ИЛИ ваше требование Role="ffff" является избыточным.

Если вы хотите ограничить EchoMethod для роли "ffff" и разрешения авторизованным пользователям для всех других методов измените код на:

class DumbClass
{
    [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] 
    public DumbClass()
    {
    }

    [PrincipalPermission(SecurityAction.Demand, Role = "ffff")]
    public string EchoMethod(string input)
    {
        return input;
    }

    [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] 
    public string OtherMethod(string input)
    {
        return input;
    }

}

Измените свой код следующим образом:

[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, вы явно указываете, что пользователь уже прошел аутентификацию, когда он мог или не мог.

Другие вопросы по тегам