通过MVC的AuthorizeAttribute来进行权限验证

随着使用项目人数的不断庞大,各种权限控制一定要完善.

下面就简单介绍一种MVC进行权限控制的方法

MSDN地址:https://msdn.microsoft.com/zh-cn/library/system.web.mvc.authorizeattribute_methods(v=vs.118).aspx

 

 1     /// <summary> 通行证登录验证过滤器</summary>
 2     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
 3     public class CheckLoginFilter : AuthorizeAttribute
 4     {
 5         /// <summary>公用,不需要登录即可访问,如登录页面</summary>
 6         public const string PublicRole = "1";
 7         /// <summary>要登录才可以访问</summary>
 8         public const string LoginRole = "2";
 9         static MenuResponseModel GetMenuResponseModel(AuthorizationContext filterContext)
10         {
11             if (filterContext.HttpContext.Session != null)
12             {
13                 if (filterContext.HttpContext.Session["MenuAndUserInfo"] == null)
14                 {
15                     //获得菜单的数据
16                     string[] userNameAndPassWord =
17                         ((FormsIdentity)filterContext.HttpContext.User.Identity).Ticket.UserData.Split('|');
18                     if (userNameAndPassWord.Length > 1)
19                         filterContext.HttpContext.Session["MenuAndUserInfo"] =
20                             new MenuService().GetMenuAndUserInfo(userNameAndPassWord[0], userNameAndPassWord[1]);
21                 }
22                 return (MenuResponseModel)filterContext.HttpContext.Session["MenuAndUserInfo"];
23             }
24             return new MenuResponseModel();
25         }
26         /// <summary>重定向或显示信息</summary>
27         static void RedirectOrShow(AuthorizationContext filterContext, string redirectUrl, string message)
28         {
29             if (filterContext.HttpContext.Request.IsAjaxRequest()) //如果是Ajax提交
30             {
31                 filterContext.HttpContext.Response.Write(message);
32             }
33             else
34             {
35                 filterContext.HttpContext.Response.Redirect(redirectUrl 
36                     + (redirectUrl.IndexOf('?')>0?"&":"?") + "message=" +filterContext.HttpContext.Server.UrlEncode(message));
37             }
38             filterContext.HttpContext.Response.End();
39             filterContext.Result = new EmptyResult();//返回一个空结果,不然页面会继续执行
40         }
41         /// <summary>验证登录</summary>
42         public override void OnAuthorization(AuthorizationContext filterContext)
43         {
44             List<string> roles = Roles.Split(',').ToList();
45             if (filterContext.HttpContext.User.Identity.IsAuthenticated)
46             {
47                 MenuResponseModel userInfoAndMenu = GetMenuResponseModel(filterContext);
48                 if (roles.Contains(PublicRole)||roles.Contains(LoginRole)) return;
49                 if (userInfoAndMenu.MenuUrl.ContainsKey(MenuService.GetMenuUrl(filterContext.HttpContext.Request.RawUrl))) return;
50                 RedirectOrShow(filterContext, "/gnselftrip/Home/Error", "原地址:" + filterContext.HttpContext.Request.RawUrl
51                     + "\r\n解析后:" + MenuService.GetMenuUrl(filterContext.HttpContext.Request.RawUrl) + "没有权限");
52             }
53             else if (filterContext.HttpContext.Request.Url != null)//获取返回页面url
54             {
55                 if (roles.Contains(PublicRole)) return;
56                 string redirectUrl = "/gnselftrip/Home/Login?ReturnUrl="//原来为FormsAuthentication.LoginUrl
57                     +filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.Url.AbsoluteUri);
58                 RedirectOrShow(filterContext, redirectUrl, "请登录!");
59             }
60         }    

这样,偶们的filter就写好了

具体使用时,先来个基类

1     [CheckLoginFilter]
2     public class AdminControllerBase : Controller
3     {
4         //do sth
5     }

然后具体的控制器继承该基类

 1 public class DemoController : AdminControllerBase
 2     {
 3         [CheckLoginFilter(Roles = CheckLoginFilter.LoginRole)]
 4         public ActionResult TestLogin()
 5         {
 6             return View();//此时只有登录的人才能访问此视图
 7         }
 8         [CheckLoginFilter(Roles = CheckLoginFilter.PublicRole)]
 9         public ActionResult TestWithVisitor()
10         {
11             return View();//此时任何人都可以访问此视图
12         }
13         public ActionResult TestPointerRole()
14         {
15             return View();//此时必须登录人权限中指定了此视图才可以访问
16          }
17     }

 

这样用实际上和使用ActionFilterAttribute来说没有什么区别(具体见MVC 过滤器 构建会员是否登录)

好处就是,我能够在我自定义的基类中继续打标签AccountFilterAttribute,来真正处理OnActionExecuting及OnActionExecuted的重写的操作(其实直接在基类里面重写都行的),使得代码不会太乱0.0

posted @ 2015-06-28 18:15  珅珅  阅读(960)  评论(0编辑  收藏  举报