MVC中权限的知识点及具体实现代码
一:知识点部分
权限是做网页经常要涉及到的一个知识点,在使用MVC做权限设计时需要先了解以下知识:
MVC中Url的执行是按照Controller->Action->View页面,但是我们经常需要在函数执行所指定的Action之前或者action方法之后处理一些逻辑,为了处理这些逻辑,ASP.NET MVC允许你创建action过滤器Filter,我们都知道在Action上使用的每一个 [Attribute]大都是自定义的Filter。
mvc提供四种类型的Filter接口:IActionFilter,IAuthorizationFilter,IExceptionFilter,IResultFilter, 这四种Filter足以满足我们所要实现的功能,它还提供了几个现
成的可以使用的Filter:OutputCacheAttribute、 HandleErrorAttribute、AuthorizeAttribute。(AuthorizeAttribute 和 HandleErrorAttribute继承自FilterAttribute 类)
其中:
IActionFilter提供的两种方法: OnActionExecuting 在调用操作方法前调用。OnActionExecuted 在调用操作方法后调用。
IResultFilter提供的两种方法:OnResultExecuting 在执行由操作方法返回的操作结果前调用。OnResultExecuted 在执行由操作方法返回的操作结果后调用。
IAuthorizationFilter是一个用于身份验证的Filter。只提供了一个void OnAuthorization(AuthorizationContext filterContext)方法。
IExceptionFilter会在出现异常的时候调用,也是只提供一个void OnException(ExceptionContext filterContext)的方法;
而4个接口的方法执行顺序如下:IAuthorizationFilter -> IActionFilter - >IResultFilter ->IExceptionFilter
【 ActionExecutedContext类包含一个 Canceled的属性,允许你取消当前的 Action】
现在我们来看一下用得最多的一个类ActionFilterAttribute:
他的继承层次结构为
System.Object
System.Attribute
System.Web.Mvc.FilterAttribute
System.Web.Mvc.ActionFilterAttribute
System.Web.Mvc.AsyncTimeoutAttribute
System.Web.Mvc.OutputCacheAttribute
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter{
}
他继承了 FilterAttribute, IActionFilter, IResultFilter三个类,通常我们在Action逻辑之前需要处理一些功能,比如权限等,因此会自定义一个Filter,它继承于
ActionFilterAttribute ,然后再在ActionFilterAttribute 中重载由接口 IActionFilter, IResultFilter继承下来的函数
void OnActionExecuting(ActionExecutingContext filterContext)
void OnActionExecuted(ActionExecutedContext filterContext)
void OnResultExecuting(ResultExecutingContext filterContext)
void OnResultExecuted(ResultExecutedContext filterContext)
其中ActionFilterAttribute有两个属性,一个是继承FilterAttribute,另一个继承Attribute
Order 获取或者设置执行操作筛选器的顺序。 (继承自 FilterAttribute。)
TypeId 当在派生类中实现时,获取该 Attribute 的唯一标识符。 (继承自 Attribute。)
例如如下代码段:
[orderFilter(RoleId="2",Order=2)]
[UserFilter(UserId="3",Order=1)]
public ActionResult test() {
return View();
}
程序在执行的顺序为:UserFilter->orderFilter->test
二:实例部分
了解上面的一些知识后,我们来看一下我设计的权限实例:
如果不知道用户,角色,组,权限之前的一些关系,建议你先看我上一篇“权限的基础知识”,这篇文章是我转过来的,觉得还不错,因为之前自己做完项目后没
分的很清楚,现在看完那篇文章,对号入座,才清楚原来我也是按照用户,角色,组,权限等这些关系来进行着 ^_^(如果下面对号入座的不对,请大家指正)
假设现在有4种功能权限: 添加功能、删除功能、发布功能、修改功能等。按照二进制01格式来设计,0表示没有该功能权限,1表示有该权限,
也就是说,按照顺序
添加 删除 发布 修改
1 1 1 1 如果只有修改功能 就是0001,
如果有添加及删除功能 就是1100,
将二进制转换为int数 添加功能:(1000=int数 8) 删除功能:(0100=int数 4) 发布功能:(0010=int数 2) 修改功能:(0001 =int数 1)
这我可以理解为 -----权限
而每个用户拥有的功能(权限)是不一样的 ,可以有多种组合, 比如1001(添加及修改权限) 0011(发布及修改权限) 1111(全部权限)
这我可以理解为-------组
而对不同用户我将他们的权限组合功能变为int 数存于user表的Permission(int)字段中,这样的话:(添加及修改权限1001=int数 9)
(发布及修改权限0011=int 数 3) (全部权限1111=int数 15)
这我可以理解为--------角色
至于用户就是我们自己数据库里面的username了.
设置用户权限:只需要将所拥有功能权限的int数相加存入数据库就可;
查看用户权限:则需要先将Permission的int值解析为二进制数,然后再看为1 的位数的int数值与对应的功能值就可。
实现: 当用户登录的时候,先查看他的Permission的int值(就是角色),将角色解析为相应的组,将每组的权限int值载入用户主体的Roles,他是一个数组形式。
(因为有一种或多种功能权限)
然后在每个需要进行权限过滤的Action上加上自定义的Filter:即在重载的OnActionExecuting方法内判断是否当前用户的Roles里面存在该功能权限,如果存在,
则进入页面,否则跳到无权限页面。
下面就是代码了,继承ActionFilterAttribute类,并且重载OnActionExecuting方法:
复制代码
publicclass RoleFilter : ActionFilterAttribute {
publicstring checkRole { get; set; } //应传入的功能权限值
publicoverridevoid OnActionExecuting(ActionExecutingContext filterContext) {
if(!string.IsNullOrEmpty(checkRole)) {
if(!filterContext.HttpContext.User.Identity.IsAuthenticated) { //判断用户是否已经登录,没登录跳转到登录页面,
string okurl = filterContext.HttpContext.Request.RawUrl;
string redirectUrl =string.Format("?ReturnUrl={0}", okurl);
string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
filterContext.Result =new RedirectResult(loginUrl);
} else { //已登录用户
bool isAuthorize = filterContext.HttpContext.User.IsInRole(checkRole);
if(!isAuthorize) //判断用户是否拥有checkRole权限,没有的话跳转到权限错误页。
filterContext.Result =new RedirectToRouteResult("Default", new RouteValueDictionary(new { Controller ="Account", Action ="AuthorizeError" }));
}
} else {
thrownew InvalidOperationException("该用户没有指定角色,请联系管理员给予角色。");
}
}
}
复制代码
在程序刚启动的时候如要读取用户角色的权限。才好做上面的比较:
复制代码
public MvcApplication() {
AuthorizeRequest +=new EventHandler(MvcApplication_AuthorizeRequest);
}
void MvcApplication_AuthorizeRequest(object sender, EventArgs e) {
//获取当前用户的角色
if(HttpContext.Current.User.Identity.IsAuthenticated) {
//下面这个方法是将role(int)转换为二进制 然后算个每个权限的int值 数组
var roles = CMSPermissionController.Instance.PermissionIdList(HttpContext.Current.User.Identity.Name.Trim()).ToArray<string>();
HttpContext.Current.User =new System.Security.Principal.GenericPrincipal(HttpContext.Current.User.Identity, roles);
}
}
复制代码
调用的过程为:
复制代码
//根据需要你也可以对整个Controller加【attribute】
[RoleFilter(checkRole ="2")]
publicclass GroupController : Controller {
public ActionResult Index() {
return View();
}
public ActionResult Create() {
return View();
}
}
//也可以对某个特定的Action添加
[RoleFilter(checkRole ="4")]
publicstring Delete(string RelaPath) {
//to do ...
}
复制代码
上面的代码基本上就可以实现了,在调试的过程中,曾经有个同事问,如果我要在Delete上也要检查checkRole="8"的时候你怎么办,我当时有点懵。。。没想
太多,就觉得那到底是先checkRole是4还是先checkRole是“8”呢,现在看来,不存在那样状况, 因为我定义的4,8等数字, 本身就是定死的权限,比如
添加 删除 发布 修改对应的权限数字是8,4,2,1;所以如果我们要对Delete本来是4的权限,来检查添加的权限8,业务逻辑上本身也是不存在的! O(∩_∩)O
还看到一篇关于权限的文章:是用当前的url来判断的,很值得学习,供以后研究:
http://www.cnblogs.com/legendxian/archive/2010/01/25/1655551.html
MVC中权限的知识点及具体实现代码的更多相关文章
- MVC中权限管理
权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少.权限管理几乎出现在任何系统里面,只要有用户和密码的系统.权限管理还是比较复杂的,有的固定到某个模 ...
- 朴素的标题:MVC中权限管理实践
基于MVC的web项目最好的权限控制方式我认为是对Action的控制,实现思路记录于此,权限管理分成两个部分授权.认证. 一.授权 1.读取当前项目中的所有需要控制的Action /// <su ...
- ASP.NET MVC中权限控制的简单实现
1.重写AuthorizeAttribute类,用自己的权限控制逻辑重写AuthorizeCore方法 public class MyAuthorizeAttribute : AuthorizeAtt ...
- easyui中权限分配和添加 前后端代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 在MVC中写Filter时经常filterContext无法代码提示HttpContext的方法和属性的原因
需要用System.Web.Abstractions.dll HttpContextBase是在System.Web.Abstractions下的,添加对System.Web.Abstractions ...
- MVC中渲染页面
mvc中当返回的字符带有html代码的时候,可以直接使用@Html.Raw(Model.description)这句代码的意思就是返回不是html编码,因此用了这句代码就不需要单独再转换一次
- FineUIMvc随笔(6)对比WebForms和MVC中表格的数据库分页
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 通过对比WebForms和MVC中表格数据库分页代码的不同,可以对 MVC 中的数据流转有更加深入的了解. WebForms 中 ...
- 在ASP.NET MVC中实现基于URL的权限控制
本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页.这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度 ...
- C# MVC 中自定义权限特性[Authorize]中对于Ajax访问的处理
在MVC中定义自己的权限特性. 下例中是简单的登录判断,登录信息存与Session中,如果Session中没有登录信息,那么就不通过. 在处理无权限的时候,判断当前请求是否为Ajax请求,如果是Aja ...
随机推荐
- ant+Jacoco 统计tomcat远程部署后项目接口自动化测试或者功能测试代码覆盖率
1.安装ant 环境,https://ant.apache.org/bindownload.cgi 2.下载jacoco包 https://www.eclemma.org/jacoco/ ,解压后, ...
- 基于HTML5 WebGL实现 json工控风机叶轮旋转
突然有个想法,如果能把一些用到不同的知识点放到同一个界面上,并且放到一个盒子里,这样我如果要看什么东西就可以很直接显示出来,而且这个盒子一定要能打开.我用HT实现了我的想法,代码一百多行,这么少的代码 ...
- Jq_DOM元素方法跟JQuery 核心函数跟JQuery 事件方法
JQuery DOM 元素 函数 描述 .get() 从队列中删除所有未运行的项目. .ind ...
- python-知识回顾-16
知识回顾 小数据池:int -5~256str 特殊字符,*数字20 ascii : 8位 1字节 表示1个字符unicode 32位 4个字节 表示一个字符utf- 8 1个英文 8位,1个字节 欧 ...
- Flask、Celery、RabbitMQ学习计划
Flask (9.16-9.23) 相关组件了解 (9.16-17) WSGI:Werkzeug 数据库:SQLAlchemy *重点查看 urls和视图 (9.18-19) session和co ...
- SE Springer小组之《Spring音乐播放器》可行性研究报告一、二(转载)
此文转载自组员小明处~~ 1 引言 1.1编写目的 <软件工程>课程,我们团队计划开发一个音乐播放器.本文档是基于网络上现有的音乐播放器的特点,团队计划实现的音乐播放器功能和团队 ...
- 第三个spring冲刺第1天
在第二阶段,我们的要实现的基本功能都已经基本是实现了,现在在第三阶段,我们会完善算法的改进.容错问题的兼容还有附加的其他功能,例如计时等
- HP 4411s Install Red Hat Enterprise Linux 5.8) Wireless Driver
pick up from http://blog.163.com/wangkangming2008%40126/blog/static/78277928201131994053617/ # cp iw ...
- Qt__QMessageBox
转自豆子空间 显示窗口 Qt提供了五个类似的接口,用于显示类似的窗口. QMessageBox::information(NULL, "Title", "Content& ...
- [转] python 模块学习 hashlib
转自: http://www.cnblogs.com/BeginMan/p/3328172.html 一.hashlib概述 涉及加密服务:14. Cryptographic Services 其中 ...