首页 > 学院 > 开发设计 > 正文

在EF的code frist下写稳健的权限管理系统:MVC过滤拦截,权限核心(五)

2019-11-17 02:11:34
字体:
来源:转载
供稿:网友

在EF的code frist下写稳健的权限管理系统:MVC过滤拦截,权限核心(五)

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]    public class PowerAttribute : FilterAttribute, IActionFilter    {        public void OnActionExecuted(ActionExecutedContext filterContext)        {            //throw new NotImplementedException();        }        /// <summary>        /// 权限标示名        /// </summary>        public string PowerName { get; set; }        /// <summary>        /// 是否超级管理员应用        /// </summary>        public bool IsSuper = false;        PRotected User LoginUser = null;        protected PowerConfig Power = null;        public IPowerConfigService powerConfigService = AutofacDependencyResolver.Current.applicationContainer.Resolve<IPowerConfigService>();                public void OnActionExecuting(ActionExecutingContext filterContext)        {            LoginUser = CacheHelper.GetCache(Constant.CacheKey.LoginUserInfoCacheKey + "_" + filterContext.HttpContext.User.Identity.Name) as User;            bool b = false;            if (IsSuper == false)            {                //非超级管理员专属操作                //权限id集合                string[] acts = LoginUser.Role.ActionIds.Split(',');                Power = CacheHelper.GetCache(Constant.CacheKey.PowerConfigCacheKey) as PowerConfig;                if (Power == null)                {                    Power = powerConfigService.LoadConfig(Constant.PowerConfigPath);                    CacheHelper.SetCache(Constant.CacheKey.PowerConfigCacheKey, Power);                }                try                {                    if (Power != null)                    {                        var p = Power.PowerList.FirstOrDefault(t => t.Name == PowerName);                        if (p != null)                        {                            if (acts.Contains(p.Id.ToString()))                            {                                //存在权限                                b = true;                            }                        }                    }                }                catch                {                    b = false;                }            }            //超级管理员都可以使用            if (LoginUser.IsSuperUser)            {                b = true;            }            #region 无权限执行            if (b == false)            { //无权限执行                if (filterContext.HttpContext.Request.IsAjaxRequest())                {                    //filterContext.Result = new JsonResult() {                    //    Data = new { pass = false, error = "无权访问" },                    //    JsonRequestBehavior=JsonRequestBehavior.AllowGet                    //};                    filterContext.Result = new ContentResult()                    {                        Content = "无权访问",                        ContentEncoding = Encoding.UTF8                    };                }                else                {                    filterContext.Controller.ViewData["ErrorMessage"] = "无权访问";//filterContext.Exception.Message + " 亲!您犯错了哦!";//得到报错的内容                    filterContext.Result = new ViewResult()//new一个url为Error视图                    {                        ViewName = "Error",/*在Shard文件夹下*/                        ViewData = filterContext.Controller.ViewData//view视图的属性中的viewdata被赋值                    };                }            }            #endregion        }    }

使用这个过滤拦截各种action的访问,做到权限的颗粒化,使用时候直接在action或者controller的头部加[Power(IsSuper=true,PowerName="权限名")],IsSuper是针对系统超级管理员设计,判断action是否为系统级别的action,一般是配置或者高权限的action使用,普通可以不写,或者为false。

power的参数配置我放到了两个地方,一个数据库,另一个是config文件,数据库可以通过我设计的导出,直接变成config。在运行时候根据角色的actionId去配置文件中取出ID对应的powername,然后根据powename进行判断(powername可以重复,有利于action的细化分组)

<?xml version="1.0"?><PowerConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <PowerGroupList>    <PowerGroup>      <GroupName>操作组一</GroupName>      <Id>1</Id>    </PowerGroup>    <PowerGroup>      <GroupName>操作组二</GroupName>      <Id>2</Id>    </PowerGroup>  </PowerGroupList>  <PowerList>    <Power>      <ParamStr>/cms/1234</ParamStr>      <Name>统计</Name>      <GroupId>1</GroupId>      <Id>2</Id>    </Power>    <Power>      <ParamStr>/cms/12345</ParamStr>      <Name>介绍</Name>      <GroupId>1</GroupId>      <Id>3</Id>    </Power>    <Power>      <ParamStr>/links/123</ParamStr>      <Name>友情链接</Name>      <GroupId>1</GroupId>      <Id>7</Id>    </Power>    <Power>      <ParamStr>/cms/123</ParamStr>      <Name>合作单位</Name>      <GroupId>1</GroupId>      <Id>8</Id>    </Power>    <Power>      <ParamStr>/proj</ParamStr>      <Name>产品展示</Name>      <GroupId>1</GroupId>      <Id>9</Id>    </Power>    <Power>      <ParamStr>/message</ParamStr>      <Name>客户留言</Name>      <GroupId>1</GroupId>      <Id>10</Id>    </Power>    <Power>      <ParamStr>/gundong</ParamStr>      <Name>滚动图</Name>      <GroupId>1</GroupId>      <Id>11</Id>    </Power>    <Power>      <ParamStr>/guangao</ParamStr>      <Name>广告位</Name>      <GroupId>1</GroupId>      <Id>12</Id>    </Power>    <Power>      <ParamStr>/cms/123</ParamStr>      <Name>文章</Name>      <GroupId>2</GroupId>      <Id>1</Id>    </Power>    <Power>      <ParamStr>/admin/ActionAdd</ParamStr>      <Name>文章查看</Name>      <GroupId>2</GroupId>      <Id>4</Id>    </Power>    <Power>      <ParamStr>/cms/12</ParamStr>      <Name>文章删除</Name>      <GroupId>2</GroupId>      <Id>5</Id>    </Power>    <Power>      <ParamStr>/cms/123</ParamStr>      <Name>文章修改</Name>      <GroupId>2</GroupId>      <Id>6</Id>    </Power>  </PowerList></PowerConfig>

上面就是生成的config,运行时候会加载到缓存,提高性能。他的生成是基于,Action和ActionGroup的,而Action和ActionGroup数据会存储到数据库,可以可视化添加。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表