利用mvc filterconfig属性实现权限验证
好久没写过博客了,突然发现最后博客更新时间是2016年,感觉好长远
权限控制基本是所有cms系统或者进销存,或者几乎所有能和业务系统扯上关系的系统都要用上的一个模块,很多都想把这个模块独立出来,权限单独统一控制,所以就出现了aop及其他相关技术操作,当然我这里说aop只是说了aop的一种功能
我今天说的是mvc自带的过滤属性就可以实现这些操作
1.前端还是需要准备一些权限信息 权限code可以是系统内部的所有页面网址,当然还有一些通用权限,如增删改审批等
2.为页面权限配置操作权限比如某个页面只有修改权限没有删除审批权限
3.下面就需要上代码了,所有controller继承一个basecontroller,在basecontroller中可以初始化一些上下文信息或定义一些通用方法,basecontroller需要一个初始化验证属性,在这个初始化属性中就可以写我们的权限控制
[MvcInitContextFilter] public class BaseController : Controller
public class MvcInitContextFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); if (filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)) { return; } var controller = filterContext.Controller as BaseController; if (controller == null) { return; } if (filterContext.IsChildAction) { controller.UserContext = UserContext.Current; return; } #region 写入usercontext //dynamic user = controller.Session[StaticString.CookieLoginInfo]; controller.UserContext = UserContext.Instanse(); UserContext.Current = controller.UserContext; controller.InitContexts(); #endregion #region 方法权限过滤 var action = filterContext.RouteData.Values["action"].ToString(); //string url = filterContext.HttpContext.Request.Url.LocalPath.ToString(); var paras = filterContext.ActionParameters as Dictionary<string, object>; //ajax方法过滤 if (filterContext.HttpContext.Request.IsAjaxRequest()) { List<string> ajaxActionList = new List<string>(); ajaxActionList.Add("save"); ajaxActionList.Add("list"); ajaxActionList.Add("setpost"); ajaxActionList.Add("del"); ajaxActionList.Add("delmore"); if (ajaxActionList.Any(o => action.ToLower().Contains(o))) { BaseRequest request = null; string Code = ""; int MenuAuthId = 0; Code = controller.Request.Params["Code"]; string MenuAuthIdStr = controller.Request.Params["MenuAuthId"]; if (string.IsNullOrEmpty(MenuAuthIdStr)) { MenuAuthIdStr = paras.Keys.Contains("MenuAuthId") ?paras["MenuAuthId"].ToString():null; } if (Code==null) { Code = paras.Keys.Contains("Code") ? paras["Code"].ToString():null; } if (MenuAuthIdStr!=null){ int.TryParse(MenuAuthIdStr,out MenuAuthId); } if ((!string.IsNullOrWhiteSpace(Code)) && MenuAuthId>0) { request = new BaseRequest(); request.Code = Code; request.MenuAuthId =MenuAuthId ; } else if (paras != null && paras.Count > 0) { KeyValuePair<string, object> pair = paras.First(); request = pair.Value as BaseRequest; } if (MenuAuthId>0&&!string.IsNullOrEmpty(Code)) { } else { //如果没有继承baserequest类就不做检查了 if (request == null) { return; } } try { List<OperateAuth> operateAuths1 = CRoleAuthDAL.GetMenuAuths(controller.UserContext.CurrentUser.UserID, request.MenuAuthId); if (string.IsNullOrEmpty(request.Code) || operateAuths1 == null || (!operateAuths1.Any(auth => auth.AuthCode.ToLower().Equals(request.Code.ToLower())))) { filterContext.HttpContext.Response.Write("您没有权限访问此页面"); filterContext.HttpContext.Response.End(); } } catch (Exception) { } } } //action方法过滤 else { var menuAuthIdStr = controller.Request.QueryString["menuAuthId"]; if (!string.IsNullOrEmpty(menuAuthIdStr)) { var menuAuthId = 0; if (menuAuthIdStr.Contains(",")) { menuAuthIdStr = menuAuthIdStr.Split(',')[1]; } menuAuthId = int.Parse(menuAuthIdStr); controller.ViewData["auth"] = CRoleAuthDAL.GetMenuAuths(controller.UserContext.CurrentUser.UserID, menuAuthId); controller.ViewData["menuAuthId"] = menuAuthIdStr; } } } #endregion }
这里面只是为了实现我自己的需求多加了一些东西,可以满足自己需求上做修改
这个MenuAuthId 是指页面权限id,对应code是前台request或者ajax里面传递的是否有这个权限然后继续下去的通用权限,如增删改
对于页面,这里还可以根据页面权限id或者页面url从数据库中查出,当前页面所能拥有的权限,然后通过viewdata的方式传递给页面,方便页面相关按钮的显示隐藏
此处做的MenuAuthId 可以用页面的url代替,这样更通用,更简单,稍作修改即可
如有建议或意见可以加群223026227