角色权限的设置

在项目中不同的登录账号之间要求所拥有的权限不一样的,所以就需要使用到角色权限的设置。需要注意的是,最高级的管理员权限是不能进行修改的,因为如果最高级的权限都修改了的话容易造成一些权限修改不回去。修改权限之后的效果我们有两个方法:
第一个方法是修改完权限之后在登录的主页面的下拉框不会显示没有权限的功能,但是有一个缺点,就是可以通过指定的地址直接进入其他没有权限的页面因此这个方法并不适用。
第二个方法则是利用后台的数据控制,没有权限的直接跳转的无权限的页面显示,这个方法虽然复杂很多,但是这个可以让客户无法通过直接输入指定地址进入页面的效果。
还要注意的就是在角色维护中处理权限的操作中还有修改数据库中的一些内容,保证路径没有问题不然第二种权限完成之后会因为一些命名的不正确导致没有显示页面而是无权限。所以在设置权限内容的时候需要检查一些数据库中的S_Module(菜单表)的表里面的命名和项目中的命名是否一致,不一致需要修改。
在制作完成角色维护的页面后,在主页面的控制器里面权限应用了调用的第一个方法:
在主页面上面封装一个方法,方法里面是页面的全部菜单。在页面加载事件里面进行调用。页面的方法发送到控制器:

$.post("/Main/SelectModularJurisdiction", { time: (new Date()).getTime().toString() }, function (objModulars) {
                console.log(objModulars);
                if (objModulars=="") {
                    window.location.href = "/";
                } else {
                    for (key in objModulars) {
                        var obj = objModulars[key];
                        if (obj.ID==0) {//如果没有权限
                            var modularName = obj.ModularName;//模块名称
                            var elId = dirIdModlarName[modularName];//根据模块名称找到元素ID[元素名称]
                            console.log(elId);
                            $("#" + elId).remove();//去掉没有的权限对应的菜单,使用选择器把菜单去掉
                            //这种方法并不能阻止别人直接通过输入菜单地址来进行跳转
                        }
                    }
                }
            });
        }

当然在控制器里面还是需要进行数据的处理:

public ActionResult SelectModularJurisdiction()
        {
            if (Session["userID"]!=null)
            {
                int userId = Convert.ToInt32(Session["userID"]);
                //读取权限信息
                var tempModulars = from tabPermission in myModel.S_Permission
                                   join tabModule in myModel.S_Module on tabPermission.moduleID equals tabModule.moduleID
                                   join tabUser in myModel.S_User on tabPermission.UserTypeID equals tabUser.userTypeID
                                   where tabUser.userID == userId && tabModule.blFun == false
                                   select new
                                   {
                                       ID = tabModule.moduleID,//模块ID
                                       Name = tabModule.moduleDescrible.Trim()//模块描述
                                   };
                //外连接(左连接)
                var userModulars = (from tbSysModular in myModel.S_Module
                                    join tabTempModulars in tempModulars
                                    on tbSysModular.moduleID equals tabTempModulars.ID
                                    into temp
                                    select new
                                    {
                                        ModularID=tbSysModular.moduleID,//模块ID
                                        ModularName=tbSysModular.moduleDescrible.Trim(),//模块名称
                                        ID=temp.FirstOrDefault()!=null? temp.FirstOrDefault().ID : 0//有该模块的权限 ID>0 没有权限ID=0
                                    }).ToList();
                return Json(userModulars, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json("", JsonRequestBehavior.AllowGet);
            }
        }

应用权限的第二种方法:
首先创建一个显示无权限的页面,在App_Start的文件夹里面创建一个新的类(FliterConfig),
其中:using FJDPXT2020.Filter;和自定义权限过滤器都是之后才引入的。

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //全局默认的过滤器-错误处理 
            filters.Add(new HandleErrorAttribute());
            //添加自定义 权限过滤器
            filters.Add(new PermissionFilter());
        }

然后在项目中创建一个Filter的文件夹命名,并且创建一个PermissionFliter.cs。
创建类的视图如下:

public override void OnActionExecuting(ActionExecutingContext filterContext)//在方法执行前 执行
        {
            //在方法执行前 执行
            base.OnActionExecuting(filterContext);

            int loginUserID = 0;
            try
            {
                //获取请求的URL
                string url = filterContext.HttpContext.Request.Url.AbsolutePath;
                //===检查是否登录
                //跳过登录检查的URL 如果URL不正确的话 就会报错服务器无法在发送 HTTP 标头之后修改 cookie
                if (url=="/" || url=="/Main/Login1" || url== "/Main/CreateValidImage" || url == "/Main/UserLogin")
                {
                    return;
                }

                loginUserID = Convert.ToInt32(filterContext.HttpContext.Session["userID"].ToString());

                //===权限检查
                if (url=="/" || url.Contains("/Main/"))
                {
                    return;
                }
                //第一种:获取在登录时 查询的权限模块信息
                List<ModuleVo> userModules = filterContext.HttpContext.Session["userModules"] as List<ModuleVo>;

                string[] strUrls = url.Split('/');//根据/分割 -> 0-空字符串,1-区域名称,2-控制器名称,3-Action
                if (strUrls.Length>=4)
                {
                    string areaName = strUrls[1];//获取区域名称
                    string controllerName = strUrls[2];//获取控制器名称
                    //一般情况权限处理--判断 区域和控制器
                    int exist=userModules.Count(o => o.moduleName == controllerName && o.parentModule.moduleName == areaName);
                    if (exist == 0)
                    {
                        filterContext.HttpContext.Response.Redirect("/Main/NoPermission");
                    }
                    //处理PNR复制功能
                    if (strUrls[3]=="CopyPNR")
                    {
                        if (userModules.Count(o => o.moduleName == "PNRCopy" && o.parentModule.moduleName == controllerName) == 0)
                        {
                            filterContext.HttpContext.Response.Redirect("/Main/NoPermission");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                filterContext.HttpContext.Response.Redirect("/Main/Login1");
            }
        }
    }

如果数据跳出try-catch则回到登录页面。
另外在项目里面还要对后面的Global.asax文件进行修改:

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            //注册全局过滤器
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }

这样第二种的权限设置的方法就完成了,如果有权限就是有内容无权限就显示无权限的页面。