• 菜单权限和非菜单权限过滤


    一、首先过滤菜单权限

    一. 此处是基于ligerUl框架的前端展示实现的菜单权限过滤,实现的步骤都大同小异,重点是本篇实现的思想。

    1. 注释掉原本固定的菜单展示

    2. 向后端发送一个getJSON异步请求

     //发送异步请求,请求的控制器和请求的方法,请求的参数,返回的参数,并且将返回的参数赋值给links
        $.getJSON("/Home/Getmenus", {}, function (data) {
            links = data;
            linksInit();
            onResize();
        })

    3. 写Getmenus方法对应的内容

    该方法中具体需要实现如下:

    a. 首先按照用户-角色-权限查找菜单权限,放在一个集合中

    b. 按照用户-权限查找菜单权限,放在一个集合中

    c. 将两个集合合并成一个集合

    d . 将禁止的集合从中清除出去

    e. 将重复的清除出去

    g. 把过滤好的集合返回到前端

    IBLL.IUserInfoService UserInfoService { get; set; }  //首先构建出该类的实例 

    #region 过滤登录用户的菜单权限 /// <summary> /// 1: 可以按照用户---角色---权限这条线找出登录用户的权限,放在一个集合中。 /// 2:可以按照用户---权限这条线找出用户的权限,放在一个集合中。 /// 3:将这两个集合合并成一个集合。 /// 4:把禁止的权限从总的集合中清除。 /// 5:将总的集合中的重复权限清除。 /// 6:把过滤好的菜单权限生成JSON返回。 /// </summary> /// <returns></returns> public ActionResult Getmenus() { //1: 可以按照用户---角色---权限这条线找出登录用户的权限,放在一个集合中。 //获取登录用户的信息 var userInfo = UserInfoService.LoadEntities(u => u.ID == Loginuser.ID).FirstOrDefault(); //获取登录用户的角色. var userRoleInfo = userInfo.RoleInfo; //根据登录用户的角色获取对应的菜单权限。 short actionTypeEnum = (short)ActionTypeEnum.MenumActionType; var loginUserMenuActions = (from r in userRoleInfo from a in r.ActionInfo where a.ActionTypeEnum == actionTypeEnum select a).ToList(); //下面语句是错误的,allUserActions是一个大集合该集合中包含了很多小的集合,所以变量b为集合类型 //var allUserActions = from r in userRoleInfo // select r.ActionInfo; //var mm = from b in allUserActions // where b.ActionTypeEnum == actionTypeEnum // select b; // 2:可以按照用户---权限这条线找出用户的权限,放在一个集合中。 var userActions = from a in userInfo.R_UserInfo_ActionInfo select a.ActionInfo; var userMenuActions = (from a in userActions where a.ActionTypeEnum == actionTypeEnum select a).ToList(); // a.ActionInfo不是一个集合,注意理解权限表与用户权限关系表之间的对应关系 //var userMenuActionse = from a in userInfo.R_UserInfo_ActionInfo // from b in a.ActionInfo // where b.ActionTypeEnum == actionTypeEnum // select b; //3:将这两个集合合并成一个集合。 loginUserMenuActions.AddRange(userMenuActions); //4:把禁止的权限从总的集合中清除。 //查询出禁止的 var forbidActions = (from a in userInfo.R_UserInfo_ActionInfo where a.IsPass == 0 select a.ActionInfoID).ToList(); //过滤查询出不包含禁止的,此处需要些一个方法 var loginUserAllowActions = loginUserMenuActions.Where(a => !forbidActions.Contains(a.ID)); //5:将总的集合中的重复权限清除。,此处需要单独写一个方法,方法的内容如下。 var lastLoginUserActions = loginUserAllowActions.Distinct(new EqualityComparer()); //6:把过滤好的菜单权限生成JSON返回。 var temp = from a in lastLoginUserActions select new { icon = a.MenuIcon, title = a.ActionInfoName, url = a.Url }; return Json(temp, JsonRequestBehavior.AllowGet); //此处返回一个temp,与指明只提交get的请求。 } #endregion

    上方去重的时候,需要单独写一个该方法

    namespace Model
    {
        public class EqualityComparer:IEqualityComparer<ActionInfo>
        {
            public bool Equals(ActionInfo x, ActionInfo y)
            {
                return x.ID == y.ID;
            }
    
            public int GetHashCode(ActionInfo obj)
            {
                return obj.GetHashCode();
            }
        }
    }

    这样就过滤成功了,但是这样还没有完,因为如果用户知道某一个菜单中的子菜单,直接输入子菜单对应的地址,还是会进入菜单中,所以这样还是不安全,那么就需要再做下方的步骤。

    就是在baseCollections中实现非菜单权限的过滤,实现的步骤就是根据登录用户,与请求的方式与请求的地址,并且根据用户,角色,权限,与用户,权限两条线去查询条件查询是否满足。并且baseCollections是所有控制器的基类,每次执行之前都会执行该类。

    using IBLL;
    using Model;
    using Spring.Context;
    using Spring.Context.Support;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace OA_MVC.Controllers
    {
        public class BaseController : Controller
        {
            public UserInfo Loginuser { get; set; }
            /// <summary>
            /// 控制器每次执行之前会先执行该方法
            /// </summary>
            /// <param name="filterContext"></param>
            protected override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                base.OnActionExecuting(filterContext);
                bool isSucess = false;
                if (Request.Cookies["sessionId"] != null)
                {
                    //首先获取到Memcache对应的cookies值。
                    string sessionId = Request.Cookies["sessionId"].Value;
                    object obj = Common.MemcacheHelper.Get(sessionId);
                    if (obj != null)
                    {
                        //UserInfo userinfo = obj as UserInfo;
                        UserInfo userinfo = Common.SerializeHelper.DeserializeToObject<UserInfo>(obj.ToString());
                        Loginuser = userinfo;
                        isSucess = true;
                        Common.MemcacheHelper.Set(sessionId, obj, DateTime.Now.AddMinutes(20));//模拟滑动过期时间
    
                        //从此处开始,完成权限校验。
                        //获取用户请求的URL地址.
                        //如果是Request.Url获取到的是http://localhost:40008/Home/home
                        //但是Request.Url.AbsolutePath获取到的是/Home/home  
                        string url = Request.Url.AbsolutePath.ToLower();
                        //获取请求的方式.
                        string httpMehotd = Request.HttpMethod;
                        //根据获取的URL地址与请求的方式查询权限表。
                        IApplicationContext ctx = ContextRegistry.GetContext();
                        IBLL.IActionInfoService ActionInfoService = (IBLL.IActionInfoService)ctx.GetObject("ActionInfoService");
                        var actionInfo = ActionInfoService.LoadEntities(a => a.Url == url && a.HttpMethod == httpMehotd).FirstOrDefault();
    
                        //判断用户是否具有所访问的地址对应的权限
                        IUserInfoService UserInfoService = (IUserInfoService)ctx.GetObject("UserInfoService");
                        var loginUserInfo = UserInfoService.LoadEntities(u => u.ID == Loginuser.ID).FirstOrDefault();
                        //1:可以先按照用户权限这条线进行过滤。
                        var isExt = (from a in loginUserInfo.R_UserInfo_ActionInfo
                                     where a.ActionInfoID == actionInfo.ID
                                     select a).FirstOrDefault();
                        if (isExt != null)
                        {
                            if (isExt.IsPass == 1)
                            {
                                return;
                            }
                            else
                            {
                                filterContext.Result = Redirect("/Error.html");
                                return;
                            }
                        }
                        //2:按照用户角色权限这条线进行过滤。
                        var loginUserRole = loginUserInfo.RoleInfo;
                        var count = (from r in loginUserRole
                                     from a in r.ActionInfo
                                     where a.ID == actionInfo.ID
                                     select a).Count();
                        if (count < 1)
                        {
                            filterContext.Result = Redirect("/Error.html");
                            return;
                        }
                        //到此处结束
                    }
    
                }
                if (!isSucess)
                {
                    filterContext.Result = Redirect("/Login/Index");
                }
            }
    
        }
    }
  • 相关阅读:
    js格式化文件大小,单位:Bytes、KB、MB、GB
    Java如何大批量从json数据源中按指定符号隔字符串,并修改、删除数据
    ExtJs定时消息提示框,类似于QQ右下角提示,ExtJs如何定时向后台发出两个请求并刷新数据实例
    Java jxl导入excel文件,导入的数字、身份证号码、手机号变成了科学计数法,解决方案
    Java 防SQL注入过滤器(拦截器)代码
    mysql8源码安装和MGR
    linux基础
    ThreadLocal
    redis缓存雪崩、穿透、击穿概念及解决办法
    ThreadLocal可能引起的内存泄露
  • 原文地址:https://www.cnblogs.com/wangjinya/p/10993452.html
Copyright © 2020-2023  润新知