6.过滤器

1) 什么是过滤器

1、过滤器(Filters)就是向请求处理管道中注入额外的逻辑。提供了一个简单而优雅的方式来实现横切关注点。

2、所谓的过滤器(Filters),MVC框架里面的过滤器完全不同于ASP.NET平台里面的Request.FiltersResponse.Filter对象,它们主要是实现请求和响应流的传输。通常我们所说的过滤器是指MVC框架里面的过滤器。

3、过滤器可以注入一些代码逻辑到请求处理管道中,是基于C#Attribute的实现。当负责调用Action的类ControllerActionInvoker在调用执行Action的时候会检查Action上面的Attribute并查看这些Attribute是否实现了指定的接口,以便进行额外的代码注入处理

 

2) Authorize授权过滤器

Authorize授权过滤器可以在控制器和Action方法使用Authorize特性,在授权过后的用户才可以访问控制器或Action方法。

新建项目,新建AuthorizeController

 

AuthorizeController里面新建两个Action,每个Action添加视图,有一个<h2>标签作为标示。

在AuthorizeAction Action方法上面加上[Authorize]特性。

 直接运行程序,地址栏输入/Authorize/index。成功打开页面。

  

地址栏输入/Authorize/AuthorizeAction。页面提示通过身份验证的用户无权访问处理请求所需的资源。证明了特性[Authorize]起到了作用。

 

 

 但是这个提示并不友好。权限不足时我们更希望会跳转到一个登陆页面。

Web.config配置文件<system.web>段内输入代码

<authentication mode="Forms">

      <forms loginUrl="~/Authorize/Index" timeout="2880" />

</authentication>

可以把不通过权限认证的用户转到/Authorize/Index页面,timeout指定用户的cookie身份信息存在2880分钟。

 

运行程序,地址栏输入/Authorize/AuthorizeAction。页面被带到了/Authorize/Index

 

先把没有没有验证的用户跳转到 Load action方法进行登陆。

 

用前一章ef生成模型的方法生成模型用于登陆。

 

新建get特性的load action,利用基架添加Createview页面。

 

基架生成的view页面。

 

再新建post特性的load action。向数据库查询符合登陆用户名和密码,如果有,就会添加用户名的cookie,维持2880分钟,再跳转到/Authorize/AuthorizeAction页面,表示成功。

 

运行程序,地址栏输入/Authorize/AuthorizeAction,然后没有权限被带到/Authorize/Load

 

输入数据库不存在的namepassword,提交,页面不进行跳转。

 

然后输入数据库有的,提交。

 

页面成功转到/Authorize/AuthorizeAction,实现了功能。而且cooike存在时间内,/Authorize/AuthorizeAction页面可以直接访问,无须登陆。

 

下面修改AuthorizeAction view页面。

 

@User.Identity.Name可以获取当前有登陆权限的用户name

新建,Lout Action方法,FormsAuthentication.SignOut()删除用户权限。回到登陆页面。

 

运行程序,地址栏输入/Authorize/AuthorizeAction。因没有权限返回/Authorize/Load,输入正确用户名和密码,登陆。

 

顺利进入/Authorize/AuthorizeAction页面,点击注销。

 

回到登陆页面,此时地址栏输入/Authorize/AuthorizeAction

 

无法跳转,证明用户权限已被删除。

 

 

1) 自定义授权过滤器

如果要自定定义授权过滤器,需要继承AuthorizeAttribute。新建Extensions文件夹,里面新建UserAuthorize类,继承AuthorizeAttribute。

 

重写OnAuthorization,AuthorizeCore,HandleUnauthorizedRequest方法。

执行OnAuthorization。

22-25行判断是否获得权限认证,没有就转至新的登陆页面。

30-36行查询请求的控制器和方法可以被那些角色访问。然后加入到Roles”角色”里面。

 

执行AuthorizeCore。

主要获取到当前拥有登陆权限的User,再在初始数据(或数据库)中查询出其角色是否能访问当前的action。返回faslse则转到HandleUnauthorizedRequest。

  

执行HandleUnauthorizedRequest。

没有授权访问时返回的视图。

 

所用到的model,放到Models文件夹内。

User:定义用户和角色。

 

Role:定义角色的名称。

 

RoleWithControllerAction:定义Controller Action只能由那些角色来访问。

 

新建DataBase文件夹,里面新建SampleData类用于初始化数据。

 

在AuthorizeController控制器中新建两个action用于简单登陆。

 

EasyLoad View

 

新建三个action Administrators,SeniorMemberJuniorMember。分别用于三种角色的权限访问。每个action 都有自己的view页面作为标示。使用自定义权限特性 [UserAuthorize(AuthorizationFailView = "Error")]。

 

运行程序,地址栏输入/Authorize/Administrators。在没有登陆用户的情况下页面会跳转到/Authorize/EasyLoad要求登陆。

 

输入”3”登陆。页面转到/Authorize/AuthorizeAction

 

尝试转到/Authorize/Administrators/Authorize/SeniorMember都提示失败,因为初始数据中用户”3”的角色只能访问/Authorize/JuniorMember

 

地址栏输入/Authorize/JuniorMember。成功。

 

点击注销。在/Authorize/EasyLoad页面登陆用户”1”。

 

因为初始数据中用户”1”的角色可以访问。/Authorize/Administrators/Authorize/SeniorMember/Authorize/JuniorMember

 

所以访问这些页面没有转到错误页面。

 

 

 

 

4) 操作和结果过滤器

操作和结果过滤器用于action执行前,action执行后,action返回前,action返回后的操作。

使用操作和结果过滤器,需要继承ActionFilterAttribute类。在Extensions文件夹下新建ActionFilters类,并继承ActionFilterAttribute。

 

转到ActionFilterAttribute,可重写四个方法。

OnActionExecuted:在执行操作方法后由 ASP.NET MVC 框架调用。

OnActionExecuting:在执行操作方法之前由 ASP.NET MVC 框架调用。

OnResultExecuted:在执行操作结果后由 ASP.NET MVC 框架调用。

OnResultExecuting:在执行操作结果之前由 ASP.NET MVC 框架调用。

  

重写了四个方法,在操作和结果过滤器执行时用filterContext.HttpContext.Response.Write(“”)在页面显示一些执行信息。

 

新建ActionFiltersController控制器,添加Index action。使用自定义的操作和结果过滤器[ActionFilters]action返回一段<h2>标签。添加View视图输出<h2>作为标示。

 

运行程序,地址栏输入/ActionFilters/Index。可以看到actionView执行前后都插入了对应的文字,对action操作和返回结果进行控制。

我们可以把操作和结果过滤器ActionFilterAttribute做到自定义权限过滤器AuthorizeAttribute同样的效果。

在文件夹Extensions新建ActionPremisFilters类,继承ActionFilterAttribute。

 

重写OnActionExecuting Action方法执行前的操作,根据登陆用户判断是否有权限,代码根自定义授权过滤器相似。

 

 

新建EasyLoad action方法,[httppost] EasyLoad action方法,用基架Create添加View视图,用于简单登陆。

 

添加SeniorMember action方法用于测试,使用操作和结果过滤器ActionPremisFilters标示,添加视图作为标示。

 

DataBase文件夹下SampleData数据初始类中添加新的数据,ActionFilters控制器和SeniorMember 方法只能由角色1,2访问。

 

运行程序,地址栏输入/ActionFilters/SeniorMember,自动转到ActionFilters/EasyLoad。输入3,登陆。

 

登陆后转到/ActionFilters/SeniorMember,显示错误。

 

清除Cookie,再次到/ActionFilters/SeniorMember,用1登陆。成功跳转,因为1在初始数据中,/ActionFilters/SeniorMember能给角色1,2进入,而用户1拥有角色1

 

5) 过滤器的顺序

授权过滤器-操作过滤器-结果过滤器-异常过滤器

类上的过滤器优先于方法上的过滤器。

 

Order属性决定过滤器先后顺序。Order默认为-1

 

重写Controller中虚方法优先于方法的过滤器。

 

 

posted @ 2017-10-19 22:43  飞天阿豪  阅读(547)  评论(0编辑  收藏  举报