MVC 控制器访问

本文关键字:访问 控制器 MVC | 更新日期: 2023-09-27 18:32:20

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

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

我不想为每个控制器操作放置属性,我已经阅读了有关路由约束自定义控制器的信息。

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

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

还有其他更好的主意吗?

MVC 控制器访问

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

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

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

如果不想将属性应用于操作并使访问逻辑远离控制器和操作定义,则可以构建全局操作筛选器。

    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);
        }
    }

或者类似的东西。

然后,在全局.asax Application_Start

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

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