首页 > 技术文章 > Mvc示例之三——用Filter进行简单身份验证

Likecon 2013-09-23 20:13 原文

Filter小解释

FiterAttribute是一个特殊的CS属性,是一个抽象类。他的父类是Attribute。而在Mvc中最常用的是ActionFilterAttribute.他是FiterAttribute的子类。同时,ActionFilterAttribute又继承了IActionFilter, IResultFilter两个接口。从这两个接口中,ActionFilterAttribute继承来四个虚方法。我们要使用ActionFiterAttribute则可以重写这几个方法。

 

如上图,这四个方法分别表示执行前、执行后,结果返回前,结果返回后。大家可以望文生义。

权限验证实现

我们这节中要实现的简单登录检查就是使用这个ActionFiterAttribute,在此,我们重写OnActionExecuting。

首先,我们定义一个ActionFiterAttribute子类,重写该方法。

 

public class CheckinLoginAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
           
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {

                filterContext.HttpContext.Response.Redirect("~/Home/Login");
                return;
            }
        }  
    }

 

 

 

此时,使用这个Fiter就可以了。我们在Action的顶部定义该属性。如下

 

[CheckinLogin]
public ActionResult GetSmallClass(string BigClass)
  {
        SmallClass_NewS news = new SmallClass_NewS();
        news.FromDataTable(EntityDMHelper.GetSmallClass_New(BigClass));
        return Json(news,JsonRequestBehavior.AllowGet);
  }

 

 

要注意的是,如果我们想公开某些页面,那么就不要在该Action上定义该属性。

如果我们觉得这样每个Action都要添加怎么办呢?可以在Controller上直接添加属性:

 

   [CheckinLogin]
    public class ArticleController : Controller
    {
        
        public ActionResult Index(int? id)
        {
            BigClass_NewS bigNews = new BigClass_NewS();
            bigNews.FromDataTable(EntityDMHelper.GetBigClass_New());
            ViewBag.News = bigNews;
            NewsS news = new NewsS();
            News model = new News();
            
            if (id.HasValue)
            {
                news.FromDataTable(EntityDMHelper.GetNewsById(id.Value));
                if (news.Count > 0)
                {
                    model = news[0];
                }
            }
            return View(model);
        }

 

这样,还是太麻烦。有人说过懒惰的程序员是个好程序员。那么我们是否还有更加简单的方法呢?Mvc3有了GlobalFilter方法,只需要在Global.asax中更改Application_Start方法就可以了:

 

 

     protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalFilters.Filters.Add(new CheckinLoginAttribute());//添加属性
            RegisterGlobalFilters(GlobalFilters.Filters);//注册
            RegisterRoutes(RouteTable.Routes);
        }

 


那么这样出现了新的矛盾,我们的登录页面及用户验证页面都被跳转,还会形成递归跳转。怎么办呢?办法总是有的,可以改写OnActionExecuting方法,如下:

 

 

  public class CheckinLoginAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            string url=filterContext.HttpContext.Request.Url.ToString();
            if(url.IndexOf("Home")>0){//将登录controller列为例外
                return;
            }
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {

                filterContext.HttpContext.Response.Redirect("~/Home/Login");
                return;
            }
        }  
    }

 


如此,就将登录页面列为例外。

 

到此为止,就成功实现了权限检查功能。好了本节到此,由于老是学习新的知识,我们下一节讲解一下如何用vs调试Mvc。

 

推荐阅读