mvc源码解读(11)-mvc四大过滤器之AuthorizationFilter
2013-02-25 14:46
429 查看
在上一篇文章中,在讲完ActionDescriptor这个类之后,我们直接跳过了这一句代码:
直接讲了ParameterDescriptor,现在我们回过头来看GetFilters方法返回一个FilterInfo实例,FilterInfo类里面的有如下成员:
我们可以看到FilterInfo里面涉及到mvc的四大过滤器:AuthorizationFilter,ExceptionFilter,ActionFilter和ResultFilter。类似于.net平台上的HttpModule对客户端发送过来的请求进行拦截从而达到某一种目的。我们知道在企业级的框架中,业务繁杂,对例如权限处理,异常处理,日志管理等这些非商业的业务,我们需要将它和业务处理抽离出来,一方面为了降低架构的耦合度,一方面可以方便我们的维护。而涉及到这些与业务无关的技术处理,比较流行的就是Aop面向切面编程的思想。Aop的核心思想在于:我引用博客园上张逸的详解http://wayfarer.cnblogs.com/articles/241024.html:"它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离”。而mvc的过滤器正是实现了Aop的这种“横切“思想。
我们首先来看AuthorizationFilter授权过滤器,顾名思义就是对系统的权限设计把关。而在mvc中所有的过滤器默认都继承了抽象类FilterAttribute,我们来看看FilterAttribute里面的一个重要成员:
属性Order用于过滤器的排序顺序,关于详细Order的用处,大家可以参考博客园上的蒋金楠老师的这一篇文章(深入探讨ASP.NET MVC的筛选器):/article/1308167.html。同时AuthorizationFilter还实现了接口IAuthorizationFilter里面的OnAuthorization方法:
实现类AuthorizeAttribute既继承了抽象类FilterAttribute又实现了IAuthorizationFilter接口,因此如果我们要自定义一个授权过滤器,我们只要让他继承自AuthorizeAttribute类即可,我们先来看看AuthorizeAttribute类里面的主要成员:
里面包含用户Users和角色Roles属性,AuthorizeCore方法用来实现授权检查,HandleUnauthorizedRequest方法是当授权失败时处理的动作,HandleUnauthorizedRequest定义如下:
授权失败之后默认是重定向到登录界面,如上英文所示。
我们前面也讲过了要实现自定义的授权方式,只要继承AuthorizeAttribute类并重写里面AuthorizeCore方法即可。
因此我们在Controller中的授权如下:
在Action中贴上Authorization标签之后,只有角色是“admin”且用户名是“linghuchong”才有权访问,这意味着,除非两个条件都满足,否则将不予授权,并会执行HandleUnauthorizedRequest方法。
FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor); |
public FilterInfo(IEnumerable<Filter> filters) { var filterInstances = filters.Select(f => f.Instance).ToList(); _actionFilters.AddRange(filterInstances.OfType<IActionFilter>()); _authorizationFilters.AddRange(filterInstances.OfType<IAuthorizationFilter>()); _exceptionFilters.AddRange(filterInstances.OfType<IExceptionFilter>()); _resultFilters.AddRange(filterInstances.OfType<IResultFilter>()); } public IList<IActionFilter> ActionFilters {get {return _actionFilters;}} public IList<IAuthorizationFilter> AuthorizationFilters {get {return _authorizationFilters;}} public IList<IExceptionFilter> ExceptionFilters {get {return _exceptionFilters;}} public IList<IResultFilter> ResultFilters {get {return _resultFilters;}} |
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离”。而mvc的过滤器正是实现了Aop的这种“横切“思想。
我们首先来看AuthorizationFilter授权过滤器,顾名思义就是对系统的权限设计把关。而在mvc中所有的过滤器默认都继承了抽象类FilterAttribute,我们来看看FilterAttribute里面的一个重要成员:
public int Order { get {return _order;} set {if (value < Filter.DefaultOrder) {throw new ArgumentOutOfRangeException("value", MvcResources.FilterAttribute_OrderOutOfRange);} _order = value;} } |
public interface IAuthorizationFilter { void OnAuthorization(AuthorizationContext filterContext); } |
public string Roles { get {return _roles ?? String.Empty;} set {_roles = value;_rolesSplit = SplitString(value);} } public string Users { get {return _users ?? String.Empty;} set {_users = value;_usersSplit = SplitString(value);} } protected virtual bool AuthorizeCore(HttpContextBase httpContext) public virtual void OnAuthorization(AuthorizationContext filterContext) protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) { // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs. filterContext.Result = new HttpUnauthorizedResult(); } internal static string[] SplitString(string original) { if (String.IsNullOrEmpty(original)) {return new string[0];} var split = from piece in original.Split(',') let trimmed = piece.Trim() where !String.IsNullOrEmpty(trimmed) select trimmed; return split.ToArray(); } |
public class HttpUnauthorizedResult : HttpStatusCodeResult { // HTTP 401 is the status code for unauthorized access. Other code might // intercept this and perform some special logic. For example, the // FormsAuthenticationModule looks for 401 responses and instead redirects // the user to the login page. private const int UnauthorizedCode = 401; public HttpUnauthorizedResult(): this(null) {} public HttpUnauthorizedResult(string statusDescription) : base(UnauthorizedCode, statusDescription) {}} |
我们前面也讲过了要实现自定义的授权方式,只要继承AuthorizeAttribute类并重写里面AuthorizeCore方法即可。
protected virtual bool AuthorizeCore(HttpContextBase httpContext) { IPrincipal user = httpContext.User; if (!user.Identity.IsAuthenticated) { return false; } if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) { return false; } if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) { return false; } return true; } |
[Authorization(Roles="admin",Users = "linghuchong")] public ActionResult IsLogin() { return View(); } |
相关文章推荐
- mvc源码解读(14)-mvc四大过滤器之ExceptionFilter
- mvc源码解读(12)-mvc四大过滤器之ActionFilter
- mvc源码解读(13)-MVC四大过滤器之ResultFilter
- mvc源码解读(15)-数据绑定组件ModelBinder之ModelBinderAttribute
- ASP.NET MVC 重点教程一周年版 第六回 过滤器Filter
- ASP.NET MVC 过滤器Filter
- ASP.NET MVC 重点教程一周年版 第六回 过滤器Filter 【转】
- 【转】ASP.NET MVC 过滤器Filter
- mvc源码解读(17)-数据绑定组件ModelBinder之ModelBinders
- ASP.NET MVC 重点教程一周年版 第六回 过滤器Filter
- caffe源码解读(11)-triplet_loss_layer.cpp
- jpcsp源码解读11:近期笔记
- ASP.NET MVC 重点教程一周年版 第六回 过滤器Filter
- MVC源码分析 - Authorize授权过滤器
- MVC 过滤器Filter
- Asp.net MVC源码分析--Filter种类以及调用优先级
- [ASP.NET MVC 小牛之路]11 - Filter
- ASP.NET MVC 重点教程一周年版 第六回 过滤器Filter
- Spring+SpringMVC+Mybatis(SSM)框架搭建教程(五)-扩展:过滤器Filter应用
- 11、过滤器Filter