ASP.NET MVC权限控制思路
在系统开发的时候一个老生常谈的权限管理问题,翻阅了很多的网络资料,但是总感觉离实际使用还有一段距离,其实权限控制无非就几个“请求、页面按钮、字段显示”, 对于前端权限就需要配合js了, 这里主要展示我这些年来一直使用的一个关于权限管理的案例,如果你只是写一个简单的cms系统,那么下面代码其实拷贝就可以用了,如果是需要进行较大型系统开发就需要进一步封装, 下面是我的思路,写的不好大家勿喷哈,有不同意见的留下一起探讨。
1、在mvc开发时路由中包含了我们所有请求信息(controller、action、url全文),而mvc又提供了过滤器的机制,因此我们将权限管理封装到过滤其中。首先把每个controller的继承封装一个basecontroller,这个controller基类可以编写一些直接调用的方法,例如session等。
/// <summary> /// 系统基础控制器类 /// </summary> public abstract class baseuicontroller : controller { /// <summary> /// 页面初始化过程 /// </summary> protected override void initialize(system.web.routing.requestcontext requestcontext) { requestcontext.httpcontext.response.cache.setcacheability(httpcacheability.nocache); base.initialize(requestcontext); } /// <summary> /// 内容返回 /// </summary> /// <param name="content">特定内容供js参考是否含流程定义等动作。</param> /// <param name="contenttype"></param> /// <param name="contentencoding"></param> /// <returns></returns> protected override contentresult content(string content, string contenttype, encoding contentencoding) { return base.content(content, contenttype, contentencoding); } /// <summary> /// 登陆用户id (session存储) /// </summary> public long logineduserid { get { object uid = ant.ui.controls.sessionconfig.getsession("uid"); if (session == null || uid == null) return -1; else { return (long)uid; } } set { ant.ui.controls.sessionconfig.setsession("uid", value); } } /// <summary> /// 获取url参数值,返回 null 或 值 /// </summary> /// <param name="keyname">参数名</param> public string requesturlparams(string keyname) { if (array.indexof(request.querystring.allkeys, keyname) >= 0) return request.querystring[keyname].tostring(); else return null; } }
2、这个时候我们编写一个过滤器,在这个过滤器中可以在请求的controller中获取controller名称和action名称。 有了这两个名称就能定位到具体的页面了,当然在得到页面之前我们可以判断用户是否已经登录。而页面权限页已经用数据库保存起来:a用户或r角色对某一个controller/action的页面(这个页面可能是新增信息、修改、删除信息的请求链接)是否有访问权限。
/// <summary> /// 用户登录过滤器 /// </summary> public class userloginedfilter : authorizeattribute { public string name { get; set; } /// <summary> /// 页面授权过程(验证用户登录状态) /// </summary> /// <param name="filtercontext"></param> public override void onauthorization(authorizationcontext filtercontext) { ui.controllers.baseuicontroller _controllerobj = (ui.controllers.baseuicontroller)filtercontext.controller; string controllerstr = _controllerobj.controllercontext.routedata.values["controller"].tostring(); string actionstr = _controllerobj.controllercontext.routedata.values["action"].tostring(); //用户尚未登陆 或 登陆超时。 if (_controllerobj.logineduserid == -1) { usererror.loginerror(); } // 权限验证 根据 controller 与 action(这里可以将权限缓存取出来进行用户匹配,如果被拒绝可以抛出异常) else if ( controllerstr.tolower() == "admin" && actionstr.tolower() == "login") { throw new httpexception("权限验证。" + _controllerobj.controllercontext.controller.tostring()); } base.onauthorization(filtercontext); } }
3、此时页面调用时就不用在每个action中编写权限验证代码啦(有些权限验证的源码会在action上增加过滤器,为了偷懒硬是想方设法把权限封装成直接在controller类上添加一次过滤器就能完成的实现)
[userloginedfilter] public class admincontroller : ui.controllers.baseuicontroller { /// <summary> /// 登陆(登陆页面不需要权限验证,增加allowanonymous特性) /// </summary> [allowanonymous] public actionresult login(formcollection form) { return view(); } /// <summary> /// 主界面 /// </summary> public actionresult index() { return view(); } }
上面只是我在系统开发过程中对于权限管理的一个思路,也实实在在的应用到了一些系统中,当然上面这些代码只能勉强判断是否登陆,如果你需要对数据权限、页面权限、字段权限进行管理那么就需要进一步的扩展。如果需要在抛出异常后将异常信息友好的返回给客户端,那你仍然需要在global中捕获返回状态码以及错误信息。因此我说这只是我的一个思路,路过的朋友给我建议。多谢!
推荐阅读
-
Asp.net MVC中获取控制器的名称的方法
-
ASP.NET MVC从视图传参到控制器的几种形式
-
详解Asp.Net MVC——控制器与动作(Controller And Action)
-
ASP.NET在MVC控制器中获取Form表单值的方法
-
asp.net MVC通用权限管理系统-响应式布局-源码
-
asp.net core 使用 AccessControlHelper 控制访问权限
-
Asp.net Core MVC中怎么把二级域名绑定到特定的控制器上
-
ASP.NET MVC5基础-控制器(Controller)详解
-
ASP.NET MVC从视图传参到控制器的几种形式
-
构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(24)-权限管理系统-将权限授权给角色