3

我们的应用程序正在从 WebForms 迁移到 MVC。我们有不同的方式来处理授权。查询数据库视图以验证用户授权。此视图根据每个用户返回所有菜单层次结构。例如,如果 User1 试图访问名为 SecretList.aspx 的页面,则通过菜单层次结构(在 auth 后保存在 HTTP Session 中)应用搜索以检查访问权限。如果该用户存在与 SecretList.aspx 相关的菜单项,则授予访问权限。

我的问题是,如何在 ASP.NET MVC 3 中实现这种方法?

我不想为每个控制器操作放置属性,并且我已经阅读了有关Route ConstraintsCustom Controller的信息。

要路由约束,我可以访问 HTTP 会话并检索我的菜单层次结构以进行授权查询吗?

对于自定义控制器,我应该考虑重载哪种方法?在控制器执行完整的操作代码之前,我可以检查授权并重定向到另一个视图吗?

还有其他更好的主意吗?

4

2 回答 2

2

我将使用全局添加到所有操作的自定义操作过滤器,它的工作方式与内置的授权属性非常相似。动作过滤器在路由解析并创建控制器后运行(因此传递给控制器​​的任何内容都必须可由任何用户构造),然后它可以检查用户是否可以执行动作,或者是否应该返回另一个 ActionResult。

我强烈建议查看 MVC 源代码(或使用 ILSpy 之类的工具)来查看授权属性的代码。

您可以使用自定义路由约束,但这实际上意味着用户不存在该路由,而不是不允许他们访问。

于 2012-04-25T02:29:15.897 回答
1

如果您不想将属性应用于您的操作并使访问逻辑远离控制器和操作定义,您可以构建一个全局操作过滤器。

    public class MenuAccessAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting (ActionExecutingContext filterContext)
        {
            var requestRoute = filterContext.RouteData.Route;

            var currentUser = WebWorker.CurrentUser; // Or wathever is your thing to get the current user from session

            if (currentUser != null && !MenuAccessService.UserHasAccessToRoute(currentUser, requestRoute))
            {
                filterContext.Result = new RedirectToRouteResult("MenuAccessDenied");
            }

            base.OnActionExecuting(filterContext);
        }
    }

或类似的东西。

然后,在 global.asax Application_Start

        GlobalFilters.Filters.Add(new MenuAccessAttribute());

但是,如果我是你,我会花一些时间使用 asp.net mvc Roles 调整我的访问逻辑,实现自定义 RoleProvider 并使用正确的 Authorize 属性装饰我的控制器和操作。

于 2012-04-25T13:29:35.267 回答