Разрешить или запретить запуск метода в .NET - PullRequest
3 голосов
/ 09 января 2010

Мне нужно организовать некоторую простую защиту в классе, в зависимости от значения перечисления. Все, что я могу выяснить, это использовать атрибут метода, а затем запустить проверку, а затем, если она не удастся, выдать исключение. Пример:

    [ModulePermission(PermissonFlags.Create)]
    public void CreateNew()
    {
        CheckPermission();
        System.Windows.Forms.MessageBox.Show("Created!");
    }
    protected void CheckPermission()
    {
        var method = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod();
        if (!flags.HasFlag(method.GetCustomAttributes(true).Cast<ModulePermissionAttribute>().First().Flags))
        {
            throw new ApplicationException("Access denied");
        }
    }

Есть ли более элегантный или простой способ сделать это, например, просто вызвать событие при запуске метода?

Ответы [ 4 ]

6 голосов
/ 09 января 2010

Почему бы просто не использовать стандартный Code Access Security вместо переопределения обработки атрибутов и обхода стека?

Я думаю, что если вы прочитаете связанную документацию, вы увидите, что то, что у вас есть, далеко не соответствует тому, что необходимо для достижения реальной безопасности. К счастью, эта проблема hard уже решена ...

3 голосов
/ 09 января 2010

Не с перечислением, а со строками - вуаля (принудительно выполняется в среде выполнения, даже в режиме полного доверия):

public static class PermissionFlags {
    public const string Create = "Create";
}

[PrincipalPermission(SecurityAction.Demand, Role = PermissionFlags.Create)]
public void CreateNew() {
    System.Windows.Forms.MessageBox.Show("Created!");
}

Все, что вам нужно сделать сейчас, это представлять пользователя в качестве принципала. Это сделано для вас в ASP.NET, и есть плагин winform (в VS2008 и т. Д.) Для использования ASP.NET для членства. Это может быть настроено для ванильных winforms и WCF, также; на самом базовом уровне, GenericPrincipal / GenericIdentity:

// during login...
string[] roles = { PermissionFlags.Create /* etc */ };
Thread.CurrentPrincipal = new GenericPrincipal(
    new GenericIdentity("Fred"), // user
        roles);

Но вы можете достаточно легко написать свои собственные основные / идентификационные модели (например, отложенные / кэшированные проверки доступа).

0 голосов
/ 09 января 2010

Возможно, вы захотите посмотреть на это с помощью чего-то вроде PostSharp , что даст вам основу для применения атрибутов, чтобы вам не нужно было выполнять проверку в вашем методе. Это может, однако, увеличить сложность в зависимости от того, как доступны текущие активные флаги. Вам, вероятно, понадобится некоторый класс для кэширования текущих разрешений для текущего пользователя.

0 голосов
/ 09 января 2010

Вы можете взглянуть на Аспектно-ориентированное программирование. Посмотрите, например, Postsharp , который позволит вам «сплетать» некоторую дополнительную логику во время компиляции с помощью методов, которые вы украсили своим атрибутом ModulePermission.

При этом вам больше не придется вызывать метод CheckPermission внутри этого «защищенного» метода, так как эта логика может быть сплетена с помощью Postsharp.

(Некоторое время назад я играл с Postsharp: http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...