WebForm
在做WebForm的时候,如果我们要实现某页面登陆后才能访问,这个非常容易实现
public partial class IndexForm : Page { protected void Page_Load(object sender, EventArgs e) { //检查是否登录(session/cookie),失败跳转登录,成功继续访问 } }
但是实际工作中,不会只有一个页面需要权限检查,当我们面对多个页面的时候,该如何处理呢?这个时候一般会采取下列这种处理方式:
1 public partial class IndexForm : BasePage 2 { 3 protected void Page_Load(object sender, EventArgs e) 4 { 5 //do something 6 } 7 } 8 9 public partial class BasePage : Page 10 { 11 /// <summary> 12 /// Pre_Init页面加载最早发生的事件 13 /// </summary> 14 /// <param name="sender"></param> 15 /// <param name="e"></param> 16 public void Pre_Init(object sender, EventArgs e) 17 { 18 //检查用户登录(session/cookie)成功就继续,失败就跳转到登陆页 19 //需要检查的页面就继承BasePage 20 if (true) 21 { 22 //继续访问 23 } 24 else 25 { 26 //跳转登录 27 } 28 } 29 }
流程图
这是一个通过继承方式的解决方法,当我们页面需要权限验证的时候,只需要继承我们的带有验证方法的BasePage,而不需要验证的页面,只需要继承BasePageWithoutAuth,但是,当功能比较复杂的时候,用户登录还能用BasePage处理, 而异常处理,日志处理,缓存处理等这些可能这种方式就解决不了, 就必须在每个页面内处理完成,这就导致了很多页面重复出现了相同功能的代码
filter与AOP
AOP(Aspect Oriented Programming)面向切面编程:在不破坏类型封装的前提下,额外的添加功能.
filter即过滤器,是AOP思想在mvc中的一种具体实现,对于webform中出现的上述问题,在mvc框架中能够用filter以AOP的方式解决,
过滤器是在执行某一个方法之前,先去执行其他的某些操作,当执行完成后再确定后续动作。相当于在我们具体方法的业务逻辑之外又额外的添加了一些功能,例如权限认证,异常处理,日志记录等,我们可以把我们的业务逻辑与这些功能组合起来,而又不会被影响
filter之权限认证自定义扩展
上面说到过滤器filter可以实现请求方法前做权限校验、登录校验等,比如说只有登录的用户才可以访问这个方法,需要进行Session的校验。如果有很多的控制器中的方法都需要校验session,后期维护也是非常的不方便的,所以只需要将这种校验放在Filter中就可以了。
MVC框架自带有默认权限认证的特性[Authorize]
1 namespace System.Web.Mvc 2 { 3 // 4 // 摘要: 5 // 指定对控制器或操作方法的访问只限于满足授权要求的用户。 6 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 7 public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter 8 { 9 // 10 // 摘要: 11 // 初始化 System.Web.Mvc.AuthorizeAttribute 类的新实例。 12 public AuthorizeAttribute(); 13 14 // 15 // 摘要: 16 // 获取或设置有权访问控制器或操作方法的用户角色。 17 // 18 // 返回结果: 19 // 有权访问控制器或操作方法的用户角色。 20 public string Roles { get; set; } 21 // 22 // 摘要: 23 // 获取此特性的唯一标识符。 24 // 25 // 返回结果: 26 // 此特性的唯一标识符。 27 public override object TypeId { get; } 28 // 29 // 摘要: 30 // 获取或设置有权访问控制器或操作方法的用户。 31 // 32 // 返回结果: 33 // 有权访问控制器或操作方法的用户。 34 public string Users { get; set; } 35 36 // 37 // 摘要: 38 // 在过程请求授权时调用。 39 // 40 // 参数: 41 // filterContext: 42 // 筛选器上下文,它封装有关使用 System.Web.Mvc.AuthorizeAttribute 的信息。 43 // 44 // 异常: 45 // T:System.ArgumentNullException: 46 // filterContext 参数为 null。 47 public virtual void OnAuthorization(AuthorizationContext filterContext); 48 // 49 // 摘要: 50 // 重写时,提供一个入口点用于进行自定义授权检查。 51 // 52 // 参数: 53 // httpContext: 54 // HTTP 上下文,它封装有关单个 HTTP 请求的所有 HTTP 特定的信息。 55 // 56 // 返回结果: 57 // 如果用户已经过授权,则为 true;否则为 false。 58 // 59 // 异常: 60 // T:System.ArgumentNullException: 61 // httpContext 参数为 null。 62 protected virtual bool AuthorizeCore(HttpContextBase httpContext); 63 // 64 // 摘要: 65 // 处理未能授权的 HTTP 请求。 66 // 67 // 参数: 68 // filterContext: 69 // 封装有关使用 System.Web.Mvc.AuthorizeAttribute 的信息。filterContext 对象包括控制器、HTTP 上下文、请求上下文、操作结果和路由数据。 70 protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext); 71 // 72 // 摘要: 73 // 在缓存模块请求授权时调用。 74 // 75 // 参数: 76 // httpContext: 77 // HTTP 上下文,它封装有关单个 HTTP 请求的所有 HTTP 特定的信息。 78 // 79 // 返回结果: 80 // 对验证状态的引用。 81 // 82 // 异常: 83 // T:System.ArgumentNullException: 84 // httpContext 参数为 null。 85 protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext); 86 } 87 }