MVC过滤器使用实例
我明白眼前都是气泡,安静的才是苦口良药。 明白什么才让我骄傲,也明白你!——2019/1/21
过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,只响应特定内容给那些有特定权限的用户,过滤器理论上有以下功能:
- 判断登录与否或用户权限
- 决策输出缓存
- 防盗链 防蜘蛛
- 本地化与国际化设置
- 实现动态Action(做权限管理系统的好东西)
- 决策输出缓存 防盗链 防蜘蛛 本地化与国际化设置 实现动态Action(最适合做权限管理系统)
- 异常处理
最常用的应该是权限管理,和异常处理。会分为两篇介绍,这里先上权限管理:
先看框架内自带 的Authorize,注释一目了然,访问只限于满足授权要求的用户。这里大家肯定会有个疑问,什么才是满足授权了呢?往后面看
这里有两个视图,Index没有加授权验证,welcome加了
public ActionResult Index(){return View();}//[Authorize(Users = "ybb")][Authorize]public ActionResult Welcome(){return View();}
然后我们在web.config里配置一下:
<authentication mode="Forms"> <forms loginUrl="/Account/Login" timeout="30"/> //未通过授权验证则会被重定向到URL指定页面</authentication>
关于authentication身份验证的配置信息,可以看下 https://www.microsoft.com/china/msdn/msdnmvp/page8_1.html 里的介绍
运行项目,在地址栏里直接输入/home/index,成功打开页面,没问题。
然后我们再用同样的方法访问加了授权验证的页面:
很显然,第一个名为Index的Action是没有过滤的,任何身份的请求都可以通过,只要在浏览器的URL栏里键入:localhost:****/Home/Index 就能得到对应的视图响应;
而第二个名为Welcome的Action上面标注了[Authorize],表示这是一个只处理那些通过身份验证的URL请求,如果没有通过身份验证就请求这个Action会被带到config里配置的URL页面。既然拒绝了未验证的用户,那就登录下通过验证:
我们来模拟下用户登录:
只看user,先不管后面的角色和角色控制器(后面会用到)
//假装userModel里是从数据库取出来的数据
public class UserModel{public static List<User> users;//用户数据public static List<Role> roles;//权限数据public static List<RoleWithControllerAction> roleWithControllerAndAction;//权限对应的访问权利static UserModel(){// 初始化用户users = new List<User>(){new User(){ Id=1, UserName="ybb", RoleId=1,UserPass="123"},new User(){ Id=1, UserName="admin", RoleId=1,UserPass="123"},new User(){ Id=2, UserName ="senior1", RoleId=2,UserPass="123"},new User(){ Id=3, UserName ="senior2", RoleId=2,UserPass="123"},new User(){ Id=5, UserName="junior1", RoleId=3,UserPass="123"},new User(){ Id=6, UserName="junior2", RoleId=3,UserPass="123"},new User(){ Id=6, UserName="junior3", RoleId=3,UserPass="123"}};// 初始化角色roles = new List<Role>(){new Role() { Id=1, RoleName="管理员", Description="管理员角色"},new Role() { Id=2, RoleName="高级会员", Description="高级会员角色"},new Role() { Id=3, RoleName="初级会员", Description="初级会员角色"}};// 初始化角色控制器和Action对应类roleWithControllerAndAction = new List<RoleWithControllerAction>(){new RoleWithControllerAction(){ Id=1, ControllerName="Home", ActionName="AdminUser", RoleIds="1"},new RoleWithControllerAction(){ Id=2, ControllerName="Home", ActionName="SeniorUser",RoleIds="1,2"},new RoleWithControllerAction(){ Id=3, ControllerName="Home", ActionName="JuniorUser",RoleIds="1,2,3"},new RoleWithControllerAction(){ Id=4, ControllerName="Home", ActionName="Index", RoleIds="2,3"}};}}
新建一个AccountController,并新建两个Action:
public ActionResult Login(){return View(); }[HttpPost]public ActionResult LoginResult(){string userName = Request.Form["userName"];string userPass = Request.Form["userPass"];var user = UserModel.users.Where(u => u.UserName == userName && u.UserPass == userPass);//伪代码,验证账号密码是否正确if(user.Count()>0){FormsAuthentication.SetAuthCookie(userName, false);//这一句是关键, 创建提供的用户名称的身份验证票证,并将其添加到的响应 cookie 集合或 URL return RedirectToAction("Welcome", "Home");}else{return RedirectToAction("Login", "Account");}}
Login
当我们输入账户密码,点击登录,这次我们通过验证成功访问了welcome页面
不知道你们有没有注意到Welcome 上面我注释掉的内容,我们甚至可以设置只有名为“ybb”或者admin的用户可以访问欢迎页面:
[Authorize(Users ="ybb,admin")]public ActionResult Welcome(){return View();}
像你所想的那样,只有使用ybb或者admin登录,才可以正常显示这个页面,使用其他账号,就又会被带到登录页。这里就不贴图了,可以自己去试试看。
先不管为何在Action上标注Users = "ybb"就可以控制可以访问的用户,但从操作性上来说这样控制Action的访问权限还是很方便的。但是如果项目大,用户对应的角色和权限变化比较大,每次变化都来重新标注Action显然不合适。MVC框架提供的过滤器(Filters)就派上了用场:
上图是Asp.Net MVC框架提供的几种默认Filter:授权筛选器、操作筛选器、结果筛选器、异常筛选器,下面来一一讲解,先看演示Demo结构图:
一、授权筛选器
授权筛选器用于实现IAuthorizationFilter接口和做出关于是否执行操作方法(如执行身份验证或验证请求的属性)的安全决策。 AuthorizeAttribute类和RequireHttpsAttribute类是授权筛选器的示例。授权筛选器在任何其他筛选器之前运行。
新建一个继承AuthorizeAttribute类的UserAuthorize类,F12定位到AuthorizeAttribute类,看看内部申明:
上面演示的指定用户才可以访问就是利用了Users属性,并由基类帮助我们验证,只放指定的Users用户通过。要实现自定义的验证只需重写下OnAuthorization和AuthorizeCore方法
/// 自定义用户授权/// </summary>public class UserAuthorize : AuthorizeAttribute{/// <summary>/// 授权失败时呈现的视图/// </summary>public string AuthorizationFailView { get; set; }/// <summary>/// 请求授权时执行/// </summary>public override void OnAuthorization(AuthorizationContext filterContext){//获得url请求里的controller和action:string controllerName = filterContext.RouteData.Values["controller"].ToString().ToLower();string actionName = filterContext.RouteData.Values["action"].ToString().ToLower();//根据请求过来的controller和action去查询可以被哪些角色操作:RoleWithControllerAction roleWithControllerAction = UserModel.roleWithControllerAndAction.Find(r => r.ControllerName.ToLower() == controllerName && r.ActionName.ToLower() == actionName);if (roleWithControllerAction != null){this.Roles = roleWithControllerAction.RoleIds; //有权限操作当前控制器和Action的角色id}base.OnAuthorization(filterContext); //进入AuthorizeCore}/// <summary>/// 自定义授权检查(返回False则授权失败)/// </summary>protected override bool AuthorizeCore(HttpContextBase httpContext){if (httpContext.User.Identity.IsAuthenticated){string userName = httpContext.User.Identity.Name; //当前登录用户的用户名User user = UserModel.users.Find(u => u.UserName == userName); //当前登录用户对象if (user != null){Role role = UserModel.roles.Find(r => r.Id == user.RoleId); //当前登录用户的角色foreach (string roleid in Roles.Split(',')){if (role.Id.ToString() == roleid)return true;}return false;}elsereturn false;}elsereturn false; //进入HandleUnauthorizedRequest }/// <summary>/// 处理授权失败的HTTP请求/// </summary>protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext){filterContext.Result = new ViewResult { ViewName = AuthorizationFailView };}}
自定义好授权类就可以到控制器上使用了,我们要新建好几个页面:
[Authorize]public ActionResult Welcome(){ViewBag.Message = "普通已授权页面";return View();}[UserAuthorize(AuthorizationFailView = "Exception")] //管理员页面public ActionResult AdminUser(){ViewBag.Message = "管理员页面";return View();}[UserAuthorize(AuthorizationFailView = "Exception")] //会员页面(管理员、会员都可访问)public ActionResult SeniorUser(){ViewBag.Message = "高级会员页面";return View();}[UserAuthorize(AuthorizationFailView = "Exception")] //游客页面(管理员、会员、游客都可访问)public ActionResult JuniorUser(){ViewBag.Message = "初级会员页面";return View();}public ActionResult Exception() //无权限访问跳转的页面{return View();}
这个时候再使用UserModel里面不同权限的账号测试下:
没有达到对应的权限:就会跳转到通过AuthorizationFailView 设置的Exception页面
二、操作筛选器、结果筛选器
操作筛选器用于实现IActionFilter接口以及包装操作方法执行。IActionFilter接口声明两个方法:OnActionExecuting和OnActionExecuted。OnActionExecuting在操作方法之前运行。OnActionExecuted在操作方法之后运行,可以执行其他处理,如向操作方法提供额外数据、检查返回值或取消执行操作方法。
结果筛选器用于实现IResultFilter接口以及包装ActionResult对象的执行。IResultFilter接口声明两个方法OnResultExecuting和OnResultExecuted。OnResultExecuting在执行ActionResult对象之前运行。OnResultExecuted在结果之后运行,可以对结果执行其他处理,如修改 HTTP 响应。OutputCacheAttribute 类是结果筛选器的一个示例。
操作筛选器和结果筛选器都实现ActionFilterAttribute类,看看类里定义的方法:
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
public virtual void OnResultExecuting(ResultExecutingContext filterContext);
根据方法的名字就知道4个方法执行的顺序了:
OnActionExecuting是Action执行前的操作、OnActionExecuted则是Action执行后的操作、OnResultExecuting是解析ActionResult前执行、OnResultExecuted是解析ActionResult后执行
即:
Action执行前:OnActionExecuting方法先执行→Action执行 →OnActionExecuted方法执行→OnResultExecuting方法执行→返回的ActionRsult中的 executeResult方法执行→OnResultExecuted执行
完全可以重写OnActionExecuting方法实现上面授权筛选器一样的功能,因为OnActionExecuting方法是在Action方法执行前运行的,自定义一个实现ActionFilterAttribute类的ActionFilters类。
这里的Demo我没有具体的做,就不贴代码了,不过这次是继承ActionFilterAttribute类,要注意下,其他的写法差不多。
三、异常筛选器
异常筛选器用于实现IExceptionFilter接口,并在ASP.NET MVC管道执行期间引发了未处理的异常时执行。异常筛选器可用于执行诸如日志记录或显示错误页之类的任务。自定义异常筛选器继承自HandleErrorAttribute
具体的Demo我单独写了一篇博客方便以后自己做异常处理和日志记录的时候查看和Copy代码
地址:https://blog.csdn.net/qq_41885871/article/details/86594338
源文参考自:https://www.cnblogs.com/oppoic/p/mvc_authorization_action_result_exception_filters.html
MVC过滤器使用实例相关推荐
- ASP.NET MVC 过滤器(一)
ASP.NET MVC 过滤器(一) 前言 前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程中的各种注入点,按照常理来说篇幅应该到了讲解控制器内部的执行过程以及模型绑定.验证这些知识了.但是呢 ...
- ASP.NET MVC 过滤器(五)
ASP.NET MVC 过滤器(五) 前言 上篇对了行为过滤器的使用做了解说,假设在控制器行为的运行中遇到了异常怎么办呢?没关系,还好框架给我们提供了异常过滤器,在本篇中将会对异常过滤器的使用做一个大 ...
- asp.net MVC 过滤器使用案例:统一处理异常顺道精简代码
asp.net MVC 过滤器使用案例:统一处理异常顺道精简代码 参考文章: (1)asp.net MVC 过滤器使用案例:统一处理异常顺道精简代码 (2)https://www.cnblogs.co ...
- DynamicData for Asp.net Mvc留言本实例 中篇 新建.删除.数据验证
上篇咱完成了显示列表的功能,下面接着来 也许您有疑问,这个显示列表不是和正常的Asp.net Mvc差不多吗?也是个foreach只是由原来的<%=字段%>变成了<% Html.Re ...
- ASP.NET MVC过滤器(一)
MVC过滤器是加在 Controller 或 Action 上的一种 Attribute,通过过滤器,MVC 网站在处理用户请求时,可以处理一些附加的操作,如:用户权限验证.系统日志.异常处理.缓存等 ...
- ASP.NET MVC 过滤器(三)
ASP.NET MVC 过滤器(三) 前言 本篇解说行为过滤器的运行过程,过滤器实现.使用方式有AOP的意思.能够通过学习了解过滤器在框架中的运行过程从而获得一些AOP方面的知识(在顺序运行的过程中, ...
- pring MVC过滤器-HttpPutFormContentFilter
在Spring MVC过滤器-HiddenHttpMethodFilter中我们提到,jsp或者说html中的form的method值只能为post或get,我们可以通过HiddenHttpMetho ...
- 跟我一起学.NetCore之MVC过滤器,这篇看完走路可以仰着头走
前言 MVC过滤器在之前Asp.Net的时候就已经广泛使用啦,不管是面试还是工作,总有一个考点或是需求涉及到,可以毫不疑问的说,这个技术点是非常重要的: 在之前参与的面试中,得知很多小伙伴只知道有一两 ...
- Spring MVC过滤器-HttpPutFormContentFilter
在Spring MVC过滤器-HiddenHttpMethodFilter中我们提到,jsp或者说html中的form的method值只能为post或get,我们可以通过HiddenHttpMetho ...
最新文章
- 搭建基础架构-ResultMsg
- 成本计算引擎动态规则解析技术详解
- Android之用netcfg命令获取手机虚拟网卡tun0的信息
- 链表之删除双链表倒数第K个节点
- 孙悟空!登上 Nature !
- @SpringBootApplication
- undefined reference to `dlclose‘问题解决方法
- smb文件共享_使用SMB文件共享作为存储替代方案
- 25. 文件系统——源程序的编译安装(make,make install,ldd,ldconfig -v)
- Python——数据结构——图——邻接矩阵
- AutoRunner安装出错怎么解决
- 推荐几个免费下载破解软件的网站
- linux课程以及Linux主要学习哪些内容
- WebSocket网页聊天室
- 不用PS,也可以轻松组合漂亮的图片—135编辑器拼图教程
- 关于 android 远程控制(pc 控制手机)
- 互联网下半场,苏宁“拼购村”如何打造现象级模式
- 工具篇——MoneyFormatUtil(用于将人民币小写金额转换成大写金额)
- 【1.6万字】连续抓屏保存为Gif动图 【keyboard库、PIL库、imageio库和pygifsicle库 探索】
- Tableau 日月环比同比