我们的应用程序正在从WebForms迁移到MVC。我们有不同的方式来处理授权。查询数据库视图以验证用户授权。根据每个用户,此视图返回所有菜单层次结构。例如,如果User1正在尝试访问名为SecretList.aspx的页面,则通过菜单层次结构(在auth之后保存在HTTP会话中)应用搜索以检查访问权限。如果该用户存在与SecretList.aspx相关的菜单项,则授予访问权限。
我的问题是,如何在ASP.NET MVC 3中实现这种方法?
我不想为每个Controller Action添加属性,我已经阅读了路径约束和自定义控制器。
要路由约束,我可以访问HTTP会话并检索我的菜单层次结构以进行授权查询吗?
要自定义控制器,我应该考虑哪种方法重载?在Controller执行完整的Action代码之前,我可以检查授权并重定向到另一个视图吗?
还有其他更好的主意吗?
答案 0 :(得分:2)
我会使用全局添加到所有操作的自定义操作筛选器,它与内置的授权属性非常相似。在路由解析并创建控制器之后运行操作过滤器(因此传递给控制器的任何内容都必须由任何用户构造),然后它可以检查用户是否可以执行操作或者是否应该返回另一个ActionResult。
我强烈建议您查看MVC源代码(或使用ILSpy之类的工具)来查看授权属性的代码。
您可以使用自定义路由约束,但这实际上意味着用户不存在路由,而不允许他们访问。
答案 1 :(得分: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属性装饰我的控制器和操作。