过滤器作为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的童鞋 点我下载

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

MVC4学习笔记之--身份认证过滤器的更多相关文章

  1. Asp-Net-Core学习笔记:身份认证入门

    前言 过年前我又来更新了~ 我就说了最近不是在偷懒吧,其实这段时间还是有积累一些东西的,不过还没去整理-- 所以只能发以前没写完的一些笔记出来 就当做是温习一下啦 PS:之前说的红包封面我还没搞,得抓 ...

  2. LevelDB 学习笔记1:布隆过滤器

    LevelDB 学习笔记1:布隆过滤器 底层是位数组,初始都是 0 插入时,用 k 个哈希函数对插入的数字做哈希,并用位数组长度取余,将对应位置 1 查找时,做同样的哈希操作,查看这些位的值 如果所有 ...

  3. Shiro:学习笔记(1)——身份验证

    Shiro——学习笔记(1) 1.核心概念 1.Shiro不会自己去维护用户.维护权限:这些需要我们自己去设计/提供:然后通过相应的接口注入给Shiro.2.应用代码直接交互的对象是Subject,也 ...

  4. shiro学习笔记_0300_jdbcRealm和认证策略

    使用shiro框架来完成认证工作,默认是iniRealm,如果需要使用其他的realm,需要配置. ini配置文件详解,官方文档的说明如下: [main] section 是你配置应用程序的 Secu ...

  5. asp.net mvc4 学习笔记一(基本原理)

    做了8年的asp.net webform,用过MVVM但还没用过MVC , 虽然项目不用MVC,但是还是想了解一下,今天第二天学习,以下是学习心得. VS2012默认带有asp.net mvc3和as ...

  6. ASP.NET MVC4学习笔记之总体概述

    断断续续使用ASP.NET MVC框架也有一年多了,也算积累了一些经验,唉,一直想写一些笔记好好总结一下,人太懒不想动笔,今天终于决定开始.希望自己能坚持下去. 这篇文章大体介绍ASP.NET MVC ...

  7. Linux学习笔记总结--ssh认证登录

    原理简介 SSH证书认证登录的基础是一对唯一匹配密钥: 私钥(private key)和公钥(public key).公钥用于对数据进行加密,而且只能用于加密.而私钥只能对使用所匹配的公钥,所加密过的 ...

  8. MVC4 学习笔记01

    1 . ASP.NET MVC 中 ActionResult 和 ViewResult 在使用上的区别是什么?要注意什么吗? ActionResult 是一个抽象(abstract)类,ViewRes ...

  9. AngularJs学习笔记3-服务及过滤器

    距离上次别博客有有一段时间了,因为最近公司和个人事情比较多,也因为学习新的知识所以耽搁了,也有人说Angularjs1.5没有人用了,没必要分享,我个人感觉既然开头了我就坚持把他写完,对一些还在使用或 ...

随机推荐

  1. C# Windows form application 播放小视频

    1. 下载direcly-show lib DLL点击打开链接 2. DxPlay.cs (能够在下载的样例中找到):    public class DxPlay : IDisposable { e ...

  2. php RSA 加密 与java加密互交,java解密

    <? php class encrypt{ var $pub_key; function redPukey() { $pubKey = "MIIDhzCCAm+gAwIBAgIGASY ...

  3. C语言循环中降低推断——————【Badboy】

    为了让编译器更好地优化循环,应该尽量让循环中降低推断,方法之中的一个是将推断语句整合进表达式.还是这个样例: for (int i = 0; i < 1000*10; i++) { sum += ...

  4. JAVA自带监控工具的介绍

    转:http://www.alidw.com/?p=326 相信部分同学可能还是不太了解或者很少使用,这些监控工具是jdk5.0以上才会有的,有部分是liunx特有的. 了解这些工具再做压力测试和调优 ...

  5. Nginx-安装依赖及配置详解

    依赖 在安装Nginx之前, 需确保系统已经安装了gcc. openssl-devel. pcre-devel和zlib-devel软件库 配置 Nginx的配置文件nginx.conf位于其安装目录 ...

  6. 锁定窗口,禁止更新的win32函数

    [DllImport("user32.dll", EntryPoint = "LockWindowUpdate", SetLastError = true, E ...

  7. C# NPOI操作Excel(下)

    根据自己项目需求编写,仅供参考 个人建议:使用Excel模板进行导出操作.尽量避免自己生成Excel(既繁琐又容易出BUG).大多情况下导出Excel都是固定格式,使用模板导出会方便很多. publi ...

  8. Android源代码解析之(四)--&gt;HandlerThread

    转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了AsyncTast的基本使用以及实现原理,我们知道AsyncTask内部是通过线程池和Handler实现的.通过对线程池和handler的封装实现 ...

  9. ubuntu 12.04LTS下jdk 6安装记录

    这两天突然对ubuntu产生了兴趣,决定来折腾一下,:-) 由于开发一般都是在java上进行,所以第一步就是得把环境搭建好,折腾了一会儿,现在把过程记录一下. Step 1 下载jdk6 地址是 ht ...

  10. linux学习之vimrc配置推荐

    ,gb2312,gbk,gb18030,big5 "去掉vi一致性 set nocompatible ""设置行号 set number "打开文件类型自动检测 ...