【问题标题】:ASP.NET MVC - Dynamic AuthorizationASP.NET MVC - 动态授权
【发布时间】:2011-01-24 18:30:15
【问题描述】:

我正在构建一个简单的 CMS,其中角色在管理面板中动态设置。因此,现有的授权控制器方法的方式,例如添加[Authorize(Roles="admin")],已经不够用了。角色-动作关系必须存储在数据库中,以便最终用户可以轻松地在管理面板中授予/获取其他人的权限。我该如何实现?

【问题讨论】:

    标签: asp.net-mvc content-management-system forms-authentication authorization roles


    【解决方案1】:

    如果你想控制授权过程,你应该继承AuthorizeAttribute并覆盖AuthorizeCore方法。然后只需使用 CmsAuthorizeAttribute 而不是默认值来装饰您的控制器。

    public class CmsAuthorizeAttribute : AuthorizeAttribute
    {
        public override virtual bool AuthorizeCore(HttpContextBase httpContext)
        {
            IPrincipal user = httpContext.User;
            IIdentity identity = user.Identity;
    
            if (!identity.IsAuthenticated) {
                return false;
            }
    
            bool isAuthorized = true;
            // TODO: perform custom authorization against the CMS
    
    
            return isAuthorized;
        }
    }
    

    这样做的缺点是您无法访问注入 ctor 的 IoC,因此您必须直接从容器请求任何依赖项。

    【讨论】:

    • 直接从容器中获取依赖的缺点是什么?我的 RoleProvider 实施不得不这样做...
    • @Haroon - 缺点之一是设计。通常认为最好的做法是让代码保持对 IoC 容器的无知,以减少对它的依赖(例如,您可能希望在 WP7 上重用您的代码,因为性能原因通常避免使用基于反射的容器)。
    • @Haroon - 话虽如此,MVC 3 支持通过属性装饰的属性进行过滤器属性注入。它仍然需要容器的知识,但更容易模拟。
    • 这就是我发现自己遇到的问题,mvc2 有时感觉很笨拙,但我认为如果使用容器完成工作。我宁愿不写hacky代码只是为了让事情变得“理想”
    【解决方案2】:

    这正是 ASP.NET 成员/配置文件为您所做的。它适用于 Authorize 属性。

    如果您想自己动手,您可以创建一个自定义操作过滤器,模仿标准授权操作过滤器的行为。伪代码如下。

    public MyAuthorizeAttribute : ActionFilterAttribute
    {
        public string MyRole { get; set; }
    
        public void OnActionExecuting(ControllerContext context)
        {
            if (!(bool)Session["userIsAuthenticated"])
            {
                throw new AuthenticationException("Must log in.");
            }
    
            if (!Session["userRoles"].Contains(MyRole))
            {
                throw new AuthenticationException("Must have role " + MyRole);
            }
        }
    }
    

    【讨论】:

    • 我对这些东西很陌生,但我看到了一个在代码中专门分配角色的示例,我不希望这样。例如,某些客户端可能有一个名为“工程师”的用户组,该用户组具有特定权限。我希望他能够从管理面板设置它们,而无需触及任何代码。现在,我看不出如何使用标准的 Authorize 属性来实现这一点
    • 那么您必须在某个时候在您的数据库中添加查找,也许将用户和控制器/操作名称与您在数据库中的访问规则相匹配。或类似的东西。
    【解决方案3】:

    角色-动作关系必须是 存储在数据库中

    您必须在控制器方法中检查您的安全性,除非您想继承 AuthorizeAttribute 以便它为您从数据库中查找角色。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多