过滤器作为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. libevent2源码分析之二:初始化流程

    本文并不很详细地分析初始化的各个细节,而重点分析如何将底层操作关联到event_base的相关字段.初始化工作主要是针对event_base的.libevent2支持多种底层实现,有epoll, se ...

  2. Android设置拍照或者上传本地图片

    效果例如以下: 看代码: MainActivity类中: package com.example.ceshidemo; import java.io.ByteArrayOutputStream; im ...

  3. 将DataSet转换成json

     /// <summary>        /// 把dataset数据转换成json的格式        /// </summary>        /// <para ...

  4. css学习之overlay

    CSS Overlay技巧 作者:大漠 日期:2013-11-10 点击:8  本文由大漠根据SARA SOUEIDAN的<CSS OVERLAY TECHNIQUES>所译,整个译文带 ...

  5. C# 调用adb command 读取手机型号和IMEI

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  6. MySQL学习总结(三)索引

    补充一下,上一章节中约束的一点东西.我们在为约束设置名称的时候(标识符)推荐写法“约束缩写_字段名”,这样让人看起来就会很清晰.例如:FK_Deptno,我们通过索引的名字就可以大概知道这是一个设置的 ...

  7. 转:Window10下RabbitMQ安装图文教程

    一.erlang下载安装 1.下载 下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,下载地址:http://www.erlang.org/downloads,双 ...

  8. 服务器上使用matplotlib.pyplot绘图

    在linux服务器端执行python脚本,有时候需要画图,但是linux没有GUI界面,因此需要在导入matplotlib.pyplot库之前先执行 import matplotlib as mpl ...

  9. MySql(零):Linux(CentOS7)下安装和配置MySQL5.7.20(安装包安装)

    一.下载安装包 1.在官网下载MySQL5.7安装包 mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz. 下载地址:https://dev.mysql.com/do ...

  10. DMA (直接存储器访问)

    DMA (直接存储器访问) 编辑 DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载.否 ...