过滤器概述
1、ASP.NET MVC中的每一个请求,都会分配给相应的控制器的对应方法(Action)去处理,而在这些处理的前后如果想再加一些额外的逻辑处理。
2、这可以更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,如果要只响应特定内容给那些有特定权限的用户,这时候就要用到过滤器。过滤器的使用场景包括:
- 日志,异常处理
- 身份验证和授权
- 输出缓存
- 网络爬虫的过滤
- 防盗链
- 本地化
- 动态Action
二、系统过滤器
2.2 ActionName过滤器
ActionName用于规定Action的名称,当使用此过滤器后,MVC将不再理会路径中的Action名称,而是用标记中的ActionName代替方法名中的ActionName,视图文件也需要指定对应的ActionName。
2.2 NonAction过滤器
NonAction标记一个Action只是一个普通的方法,不作为MVC的Action。
没有添加过滤器时可以正常显示,添加NonAction后,此时访问/Home/Index2将找不到Action。
2.3 RequireHttps
- 强制使用HTTPS重新发送请求。
- 当请求http://localhost/Home/IndexHttps。
- 自动切换到HTTPS请求https://localhost/Home/IndexHttps。
这个功能会随着时间推移,应用场景会越来越多,现在很多大平台(苹果软件市场,微信公众号等)要求接入的项目使用HTTPS进行通讯,并给出了过度周期,这就需要我们将普通的HTTP请求,切换到HTTPS请求方式。
2.4 ValidateInput
- 该Action是否过滤HTML等危险代码
- 上述代码表示开启安全验证,当ValidateInput(false)时则关闭输入验证。
2.5 HTTP动作过滤器
[HttpGet]、[HttpPost]、[HttpDelete]、[HttpPut]此4个过滤器用于筛选HTTP请求,[HttpGet]只处理Get请求,[HttpPost]只处理Post请求,[HttpDelete]只处理Delete请求,[HttpPut]只处理Put请求。
2.6 ValidateAntiForgeryToken
- 跨站点请求伪造(CSRF)是一种攻击方式,恶意站点向用户当前登录的易受攻击的站点发送请求。
- 防止跨站请求攻击时会在Cookie添加一个随机项,然后添加一个随机数到表单里的而ValidateAntiForgeryToken就是用于检测两项是否相等。
2.7 OutputCache过滤器
- OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数。
- Duration:缓存的时间,以秒为单位,理论上缓存时间可以很长,但实际上当系统资源紧张时,缓存空间还是会被系统收回。
2.8 VaryByParam
- VaryByParam:表示以哪个字段为标识来缓存数据,比如当“name”字段变化时,需要改变缓存(仍可保留原来的缓存),那么应该设VaryByParam为"name"。
- VaryByParam为每个不同name参数生成维持一个独立的缓存,单独计算过期时间。
三、默认授权过滤器
- 在日常手机电脑使用中,使用身份验证的地方非常多,发邮件,买东西,有时候帮忙投个票都要提示登录的。这里的某些操作,就是要经过验证授权才被允许。
- 在MVC中可以利用默认过滤器Authorize来实现。如果要通过验证,通过调用FormsAuthentication.SetAuthCookie方法来获得授权。
3.1示例
- 新建一个AdminController,里面有两个Action,并创建对应(空白)视图页面,在页面中放入文本Index作为标识方便区分。
- 在这里Index的Action是没有过滤的,任何身份的请求都可以通过,只要在浏览器的URL栏里键入: /Admin/Index就能得到对应的视图响应
- 在名为Index的Action上面标注[Authorize],表示这是一个只处理那些通过身份验证的URL请求,如果没有通过身份验证这个请求就会显示如下页面。
- 编写Login Action,第一个是处理Get请求用于响应视图页面,第二个是处理用户点击提交回发的登录表单,验证用户名密码。
- 如果正确则设置用户通过授权,并跳转到/Admin/Index页面。如果失败则显示错误信息。
[HttpPost]
public ActionResult Login(string UserName,string Password,bool RememberMe)
{
if (UserName.Trim() == Password.Trim()) //只要输入的用户名和密码一样就通过验证
{
//用户授权登录成功,RememberMe为true时cookie有效期2880分钟
FormsAuthentication.SetAuthCookie(UserName, RememberMe);
return RedirectToAction("Index", "Admin");
}
else
{
TempData["result"] = "登录失败";
return View();
}
}
[HttpGet]
public ActionResult Login()
{
return View();
}
- 使用FormsAuthentication表单授权类时需要引用命名空间System.Web.Security。
- 创建Login登录视图。
<body>
<div>
@using (Html.BeginForm())
{
<p>账户:@Html.TextBox("UserName")</p>
<p>密码:@Html.TextBox("Password")</p>
<p>记住:@Html.CheckBox("RememberMe")</p>
<p>
<input id="btnSubmit" type="submit" value="登录" />
</p>
<p>@TempData["result"] </p>
}
</div>
</body>
填写用户名密码一致即可通过验证。需要注意的是,这里使用的是Cookie保存登录状态,如果这里选择记住,就会保存登录状态2880分钟。登录成功后进入/Admin/Index页面,再次访问在不需要验证了。
登录如果用户名密码错误则显示错误信息。
四、实战演练——使用过滤器实现用户授权登录
- 任务目标
- 使用系统授权过滤器进行用户权限验证
- 链接数据库验证用户名密码
- 需求说明
- 使用授权过滤器实现后台管理页面的访问控制。
- 实现思路
- 创建数据库UserDB,创建数据表Users包含id int、UserName varchar(50)、Password
varchar(50),填入测试账户密码。 - 创建MVC项目MVC_FilterProject,创建Admin控制器。在控制器上设置[Authorize]授权特性,对整个Admin控制器中所有Action都起作用,创建Index视图。运行页面看授权是否启动。
- 配置Web.config配置文件,在system.web中配置授权方式Forms,登录地址/Account/Login。再运行刚才管理页面,测试运行效果,这时错误信息应该改成Login页面找不到。这说明配置成功了。
- 创建Account控制,编写Login Action。创建Login视图,编写登录表单。
- 处理登录表单请求,创建LINQ to
SQL类,连接数据库查询用户名密码是否匹配,如果正确设置FormsAuthentication.SetAuthCookie,授权用户访问,并页面重定向到管理页面。要使用授权类记得导入命名空间System.Web.Security。 - 在创建的LINQ toSQL类的“DataClasses1.designer.cs”文件下找的Users类中添加一个bool类型的属性RememberMe。public bool RememberMe { get; set; }
- 如果用户名或密码错误则显示错误信息,提醒用户重试。
- 在管理页面视图中显示当前用户名字,以及创建登出按钮,点击按后页面跳转到Account控制器Logout页面实现登出。
- 编写Account控制器Logout Action设置用户登出,并跳转到Login页面。
Logout.cshtml页面代码:
Login.cshtml页面代码;
Account控制器代码:
Index.cshtml页面代码:
AdminController代码: