• MVC 自定义过滤器/特性来实现登录授权及验证


    最近在做自学MVC,遇到的问题很多,索性一点点总结下。

       写过webForm项目的童鞋都知道,在执行Page_Load()之前,会执行:OnInit(EventArgs e),那么在MVC中,在执行Action方法之前,会执行什么呢?在执行MVC Action之后,又会执行什么呢?下面给出答案:

       1、OnActionExecuting  在执行操作方法之前由 MVC 框架调用。

       2、OnActionExecuted  在执行操作方法后由 MVC 框架调用。

       3、OnResultExecuting  在执行操作结果之前由 MVC 框架调用。

       4、OnResultExecuted  在执行操作结果后由 MVC 框架调用。

       根据上述,我们可以看出,在执行Action方法之前,MVC会执行OnActionExecuting()方法,这个方法在控制器中并没有展示给我们,需要我们进行重写。

       下面以程序为例进行说明:

    复制代码
    namespace WeiXinApi.Controllers
    {
        //统一授权验证
        [Authorize(Roles = "admins")]
        public class MangerController : Controller
        {
            public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
            {
                if (true)
                {
                    //执行相关操作
                   //................一般执行如下操作................
                   //读取用户登录信息,获取用户权限
                    //MVC Form验证是通过Cookies实现的,因此在此处读取Cookies 并作验证
                }
                else
                {
                    //如果验证失败,则返回登陆页
                    filterContext.HttpContext.Response.Redirect("/Home/Login");
                }
            }
    
            public MangerController()
            {
                ViewBag.NewsCount = 43;
            }
    
            public ActionResult index()
            {
                return View();
            }
            public ActionResult wei_Configs()
            {
                return View();
            }
            
    
        }
    }
    复制代码

       那么,按照上述的思路,如果你有多个Controller需要验证,那么就必须在每个Controller中重写这个方法,显然这样做是比较笨的方法,那么我们动动我们聪明的小脑袋,很快会想出一个方法:那就是继承。

       我们写一个父亲控制器,在这个父亲控制器中,我们重写这个方法,然后在需子控制器中继承父亲控制器即可,代码如下:

       

       

       看到这儿,相信做过webForm的童鞋就会想起basePage.cs中的如下代码:

       

       那么,这样定义一个父亲控制器就算完美了吗?如果有个控制器需要继续另外一个类怎么办?

       由于其已经继承了父亲控制器,那么子控制器就不能再继承其他类,这样显然降低了程序的可扩展性,我们应当怎么办呢?

       还好,MVC为我们提供了过滤器,ActionFilterAttribute里也有OnActionExecuting方法,跟Controller中的OnActionExecuting方法一样, 同是抽象实现了IActionFilter接口。

       我们新建派生类如下:

    复制代码
    namespace WeiXinApi.App_Start
    {
        public class AuthenticationAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
            {
                string cookieName = FormsAuthentication.FormsCookieName;//读取登录授权Cookies的名称
                HttpCookie authCookie = System.Web.HttpContext.Current.Request.Cookies[cookieName];//接收这个Cookies
                FormsAuthenticationTicket authTicket = null;
                try
                {
                    authTicket = FormsAuthentication.Decrypt(authCookie.Value);//我们知道MVC登录授权的Cookies是加密的,所以我们在此需要解密
                }
                catch (Exception ex)
                {
                    return;
                }
                if (authTicket != null && filterContext.HttpContext.User.Identity.IsAuthenticated)//如果Cookies不为Null 也通过验证
                {
                    string UserName = authTicket.Name;
                    CommonMethod.setCookieForMIn("UserName", UserName, 30);//用于全局,加载用户信息
                    base.OnActionExecuting(filterContext);
                }
                else
                {
                    filterContext.HttpContext.Response.Redirect("/Home/Login");//否则跳转至登陆页
                }
            }
        }
    }
    复制代码

       至于MVC登录授权的方法,大家可以参考我的博客:MVC 登录认证与授权及读取登录错误码

       在此,我们深究下ActionFilterAttribute 类的说明:

       

       在此:问大家一个问题,何为:Attribute ?

       中文名称解释为特性、属性

       MVC的数据注解与验证中会用到好多特性,譬如:

       

       那么,我们应当怎么使用新建的 AuthenticationAttribute 类呢?

       

       根据需求,大家可在类范围内使用这个特性,亦可在Action方法头上使用这个特性。

       以上便是MVC自定义过滤器特性来验证授权登录信息的方法

       祝大家有个好心情,谢谢

       @陈卧龙的博客

  • 相关阅读:
    尽可能的降低重复劳动——模板策略
    一个CSS上中下三行三列结构的Div布局
    程序员那些悲催的事儿
    给NSString增加Java风格的方法
    DIV和table页面布局的区别和联系
    cocos2d播放雪花
    时间复杂度和空间复杂度2 数据结构和算法04
    OD使用教程4 调试篇04|解密系列
    OD使用教程5 调试篇05|解密系列
    PE结构简图
  • 原文地址:https://www.cnblogs.com/wdcwy/p/6427747.html
Copyright © 2020-2023  润新知