zoukankan      html  css  js  c++  java
  • 在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数据会存储到数据库,可以可视化添加。

  • 相关阅读:
    lamp架构之一键编译安装lamp搭建wordpress和discuz脚本(基于centos)
    更换公网IP导致wordpress网站无法正常访问解决方法
    centos7一键编译安装Apache2.4.46脚本
    redis之RDB备份脚本
    一键编译安装redis5.0.9脚本(centos)
    一键二进制安装mysql8.0.19脚本(shell)
    c语言 扫雷游戏(才做了三分之一)
    C语言 数据结构单链表(未解决版)
    JAVA final关键字的使用
    JAVA 520 无限循环I love you
  • 原文地址:https://www.cnblogs.com/RainbowInTheSky/p/4611551.html
Copyright © 2011-2022 走看看