允许或禁止在.NET中运行方法

时间:2010-01-09 19:06:17

标签: c# reflection attributes methods

我需要在一个类中组织一些简单的安全性取决于枚举的值。 我能想到的只是在方法上使用属性然后运行检查然后如果失败则抛出异常。 样品:

    [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 个答案:

答案 0 :(得分:6)

为什么不使用标准Code Access Security而不是重新实现属性处理和堆栈行走?

我认为,如果您仔细阅读链接文档,您会发现您拥有的内容与实现实际安全性所需要的一致。值得庆幸的是,这个问题已经解决了......

答案 1 :(得分:3)

不是枚举,而是字符串 - 瞧(由运行时强制执行,即使是完全信任):

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作为成员资格。它也可以配置为vanilla winforms和WCF;在最基本的级别GenericPrincipal / GenericIdentity

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

但是你可以很容易地编写自己的主体/身份模型(例如,延迟/缓存访问检查)。

答案 2 :(得分:0)

您可以查看面向方面编程。 例如,查看Postsharp,这将使您能够在编译时使用ModulePermission属性修饰的方法“编织”一些额外的逻辑。

通过这样做,您不必再在'secure'方法中调用'CheckPermission'方法,因为该逻辑可以由Postsharp编织。

(前一段时间,我一直在玩Postsharp:http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html

答案 3 :(得分:0)

您可能希望使用类似PostSharp的内容来执行此操作,这将为您提供应用属性的框架,这样您就不必在方法中运行检查。然而,这可能会增加复杂性,这取决于如何访问当前活动的标志。您可能需要一些类来缓存当前用户的当前权限。