过滤器作为MVC模式中面向切面编程应用很广泛,例如身份验证,日志,异常,行为截取等。博客园里面的大神对应过滤器的介绍以及很多,MVC4中不同的过滤器也介绍得很清楚。FlyDragon  辉太 禁止吸烟 如果对过滤器还没有概念的童鞋,不妨先看看前面各位前辈的介绍(前面的文章说得已经很好了,而我是想写一个较为完整的例子)。

  此文仅作为个人学习笔记整理,如果有幸对你有所帮助,不胜荣幸。如果文中有错误的地方,感谢指正。

  如果在个人前期学习阶段,使用MVC自带的身份验证,给人的感觉就是无法自己达到自己想要的控制效果,掌握起来比较麻烦。往往在一个小的作为学习MVC的项目里面,反而自己写一个过滤器来实现相关的功能,反而觉得整个学习思路比较清晰。该实例的身份验证过滤器支持三种验证方式:

1.游客(每个人都可以访问)

2.用户(注册的用户)

3.管理员(后台管理)

一、先来看看数据库

定义了一个基础的用户表,右侧是一个权限表。右侧的权限表是固定的,一开始就把我们的权限规则数据填充在里面。设置RoleId这个字段是为了待会方便我们判断权限。

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web; namespace MyAuthorizen.Models
{
[Table("User")]
public class User
{
[Key]
public int UserId { get; set; } [DisplayName("用户名")]
[Required(ErrorMessage="用户名是必填字段")]
public string Name { get; set; } [DisplayName("密码")]
[DataType(DataType.Password)]
[Required(ErrorMessage="密码是必填字段")]
public string Password { get; set; } [DisplayName("昵称")]
public string AuthName { get; set; } public int RoleId { get; set; } public virtual Roles Role { get; set; }
} public class LoginModel
{
[DisplayName("用户名")]
[Required(ErrorMessage = "用户名是必填字段")]
public string Name { get; set; } [DisplayName("密码")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "密码是必填字段")]
public string Password { get; set; }
} public class RegisterModel
{
[DisplayName("用户名")]
[Required(ErrorMessage = "用户名是必填字段")]
public string Name { get; set; } [DisplayName("密码")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "密码是必填字段")]
public string Password { get; set; } [DisplayName("确认密码")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "密码是必填字段")]
[Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
public string ConfirmPassword { get; set; } public int RoleId { get; set; } public virtual Roles Role { get; set; }
}
}
 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web; namespace MyAuthorizen.Models
{
[Table("Roles")]
public class Roles
{
[Key]
public int RoleId { get; set; } [Required]
public string RoleName { get; set; } public virtual List<User> Users { get; set; }
}
}

由于我们的Roles表需要预先存数据在数据库中,在EF中我们这样添加种子数据

 using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web; namespace MyAuthorizen.Models
{
public class dbContext : DbContext
{
public dbContext()
: base("name=DefaultConnection")
{
Database.SetInitializer<dbContext>(new RankDBInitializer());
} public DbSet<User> Users { get; set; }
public DbSet<Roles> Roles { get; set; } } public class RankDBInitializer : DropCreateDatabaseAlways<dbContext>
{
protected override void Seed(dbContext context)
{
List<Roles> Roles = new List<Roles>();
Roles.Add(new Roles { RoleId = , RoleName = "Admin" });
Roles.Add(new Roles { RoleId = , RoleName = "User" });
Roles.Add(new Roles { RoleId = , RoleName = "Anyone" }); foreach(var item in Roles)
{
context.Roles.Add(item);
}
base.Seed(context);
}
}
}

都完成后,我们来开始写我们自己的过滤器了,类名为MyAuthFilter。要实现标签的功能我们需要继承至ActionFilterAttribute类和实现IAuthorizationFilter接口。

using MyAuthorizen.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security; namespace MyAuthorizen.Class
{
public class MyAuthFilter : ActionFilterAttribute, IAuthorizationFilter
{
public string Rank;
private int RankId = ; //通过用户名称得到的的Rank 这里初始值设定为3是因为我们游客默认的RankId为3
private int RoleId = ; //通过action的过滤参数的到的RoleId public MyAuthFilter(string Rank = "User")
{
this.Rank = Rank;
} void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)
{
using (var db = new dbContext())
{
var session = filterContext.RequestContext.HttpContext.Session["Name"];
if(session != null)
{
this.RankId = db.Users
.Where(w => w.Name == session)
.Select(s => s.RoleId)
.FirstOrDefault(); this.RoleId = db.Roles
.Where(w => w.RoleName == this.Rank)
.Select(s => s.RoleId)
.FirstOrDefault();
}
}
if (this.RankId <= this.RoleId)//如果当前用户权限大于action限制的权限,则执行action 否则跳转至登录页面
return;
filterContext.Result = new RedirectResult("/Login/Login");
}
} }

这里我们默认是登录用户权限才可以访问。

增加一个用于登录的控制器Login

 using MyAuthorizen.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace MyAuthorizen.Controllers
{
public class LoginController : Controller
{ private dbContext db = new dbContext(); [HttpGet]
public ActionResult Login()
{
return View();
} [HttpPost]
public ActionResult Login(LoginModel login)
{
var Name = db.Users
.Where(w => w.Name == login.Name)
.Where(w => w.Password == login.Password)
.Select(s => s.Name).FirstOrDefault();
if(Name != null )
{
Session["Name"] = Name;
return Redirect("/Home/Index");
}
return RedirectToAction("Login");
} [HttpGet]
public ActionResult Register()
{
//ViewBag.model = db.Users.Include("Role").ToList();
return View();
} [HttpPost]
public ActionResult Register(RegisterModel regis)
{
db.Users.Add(new User { Name=regis.Name,Password=regis.Password,RoleId = regis.RoleId});
db.SaveChanges();
return RedirectToAction("Login");
} public ActionResult LoginOut()
{
Session.RemoveAll();
Session.Clear();
return RedirectToAction("Login","Login");
} }
}

登录所用到的视图部分的代码各位看官自己添加咯!

新建一个Home控制器来看看效果吧,Home控制器里面有三个方法,分别是Index、About、Admin三个方法分别需要不同的权限。Index每个人都可以访问,About需要登录的用户才能访问,而Admin需要管理员权限的用户才能访问。

 using MyAuthorizen.Class;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace MyAuthorizen.Controllers
{
[MyAuthFilter]
public class HomeController : Controller
{
//
// GET: /Home/
[MyAuthFilter(Rank="Anyone")]
public ActionResult Index()
{
return View();
} public ActionResult About()
{
return View();
} [MyAuthFilter(Rank="Admin")]
public ActionResult Admin()
{
return View();
} }
}

如代码所示,Index需要需要把Rank的值设置为Anyone才能让每个人都可以访问。而About则不设置。默认需要登录的用户才可以访问。而Admin方法设置为Admin才能达到让管理权限的用户才能访问的功能。

首先,我们注册一个账号001,用户权限。

请注意RoleId那个表单,在实际使用中。我们提供给别人注册的表单里面是不能包含这个属性的,需要我们在后台的Action里面手动设置RoleId的值,这里我设置成2表示注册一个普通用户。

访问个人中心正常(个人中心对应的Action是About),但是我们点击管理后台的时候会自动跳转到登录页面

注册一个管理员权限的用户

访问管理页面正常

以上

如有需要demo的童鞋 点我下载

第一次写笔记 好紧张好害怕会不会被鄙视

最新文章

  1. NDT(Normal Distribution Transform) 算法(与ICP对比)和一些常见配准算法
  2. python脚本基础总结
  3. vue 一些开发姿势
  4. Swift - 计算文本高度
  5. C#中成员初始化顺序
  6. Visual C#编写3D游戏框架示例
  7. phpcms 修改后台 主页面的模板
  8. Android最佳性能实践(一)——合理管理内存
  9. 计算2的n次方的三种方法(C语言实现)
  10. 第六百二十一天 how can I 坚持
  11. C++设计模式之装饰者模式
  12. boost::asio 连接管理11 如何关闭连接
  13. MYSQL 函数复习
  14. markdown中常见的转义字符
  15. 使用jquery的load方法设计动态加载,并解决浏览器前进、后退、刷新等问题
  16. JavaScript递归
  17. jsp页面在Android系统和ISO系统的兼容性问题
  18. 阿里云盾SSL证书即将到期怎么办?
  19. 远程调用HBase出错,尝试10次后,报org.apache.hadoop.hbase.MasterNotRunningException错误
  20. Apache与php快速部署web服务

热门文章

  1. lucene 索引中文档的属性建立与不建立带来的影响总结
  2. 利用python批量缩放图片
  3. 一个页面弄懂 CSS 样式选择器
  4. iOS valueForKeyPath快速计算求和、平均值、最大、最小
  5. Android学习之ItemTouchHelper实现RecylerView的拖拽以及滑动删除功能
  6. 关于web上文章移植伴随的样式问题
  7. Java基础07 包(转载)
  8. 创建一个视图JSP文件的helloWorld.jsp
  9. android Splashy Flash小游戏
  10. CMakeList相关