• 权限管理页面控制


    我们知道对于权限管理这块,采取的思想就是RBAC

     每个用户对应一个角色,我们只需要对这个角色进行分配相应的权限即可,也就是给这个用户分配了权限,这样管理起来很方便,设计也很简答,大概就是用户表,角色表,模块表,在加上一个角色与模块对应的表就可以了,然后根据不同的用户权限,显示相应的模块或者提示没有权限访问,这里要说的就是,对每个页面的访问权限,如果都写的话,这么多的页面是个很大的工作量,类似判断用户是否登录一样,在asp.net中我们完全可以使用Forms验证来代替使用session每个页面都要判断的做法,同样,在这里我们也可以通过HttpModule来直接过滤掉没有访问权限的页面,方便多了,我们知道HttpModule可以再服务器端接收处理之前进行相关的过滤,这点给我们提供很大的方便,我们完全可以利用它的这一点,具体的来看看下:

    View Code
      public class CheckUserModule : IHttpModule
        {

            private static string loginPage = "login.aspx";
            #region IHttpModule Members
            public void Dispose()
            {
                //此处放置清除代码。
            }

            public void Init(HttpApplication context)
            {                   
                context.AcquireRequestState += new EventHandler(checkUserRight);           
            }
            
            /// <summary>
            
    /// 检测用户权限
            
    /// </summary>
            void checkUserRight(object sender, EventArgs e)
            {             
                HttpApplication application = (HttpApplication)sender;          // 获取应用程序            
                string url =  HttpContext.Current.Request.Url.ToString();       // 获取Url
                int start=url.LastIndexOf('/') + 1;                             //查找URL中最后一个/的位置
                int end=url.IndexOf('?',start);                                 //查找URL中?位置
                string requestPage = null;                                      
                if (end < 0) end = url.Length - 1;
                requestPage=url.Substring(start, end - start +1);               //得到所请求的页面
                requestPage = requestPage.ToLower();
                if (requestPage == loginPage) return;
                if (!isProtectedResource(requestPage)) return;
                User user=SJL.Web.HttpCode.WebUtility.currentUser;              //获得当前用户          
                if (user==null)
                {
                    application.Response.Redirect("~/Login.aspx");
                    return;
                }                
                if (SJL.Bll.UserRight.UserBLL.isAdmin(user)) return;                     
                //检测用户权限
                if (!SJL.Bll.UserRight.RoleRightBLL.canAccessPage(user.RoleID, requestPage))                
                    application.Response.Redirect("~/AccessDeny.htm");
            }

            /// <summary>
            
    /// 判断页面是否为受权限管理保护的资源(如Aspx等)
            
    /// </summary>
            
    /// <param name="page">所请求的页面</param>
            
    /// <returns>是否受保护</returns>
            bool isProtectedResource(string page)
            {
                page = page.ToLower();
                System.Collections.Generic.List<String> protectedFiles = 
                new System.Collections.Generic.List<string>();            //受保护资源的扩展名          
                protectedFiles.AddRange(new string[] { ".aspx"".asmx"".ashx" });
                string found=protectedFiles.Find(s => page.EndsWith(s));
                if (found == null)
                    return false;            
                ApplicationModule module = SJL.Bll.UserRight.ApplicationModuleBLL.getByUrl(page);
                if (module == nullreturn false;
                return !module.IsPublic;                                        //如果页面为公共模块则不受保护            
            }     
            #endregion

            public void OnLogRequest(Object source, EventArgs e)
            {
                //可以在此放置自定义日志记录逻辑
            }       
     
             
        }

    Web.coinfig中配置下

     <httpModules>

            <add name="CheckUserModule" type="SJL.Web.HttpCode.CheckUserModule"/>

          </httpModules>

    先判断是否登录,是否是受保护的资源,然后根据url来判断是否有权限访问!

    我们可以根据自己需要控制的权限去设置,比如一个企业级的软件,我们需要控制菜单的页面,那么这个时候,我们只需要判断
      1、.aspx结尾的文件,httpModules过滤的时候也会过滤下比如css,js,ashx等页面,在这里因为受权限保护的只有aspx结尾的,所有只需要对aspx结尾的进行过滤判断即可
      2、是否是受权限控制的页面
      3、如果没有登录,则跳到登录页面

      4、如果是受权限控制的页面,那么就看看此时登录的用户是否有访问的这个页面的url权限即可

    注意点:

      1、因为这种方式主要是对页面进行权限判断,所以为了权限设置到位,比较严,最好每一个需要权限保护的功能都单独做一个页面,不要和其他页面套在一起,放置权限设置混乱

      2、判断权限页面的时候,对访问的页面和数据库保存的页面都要去除参数和目录,比如/user/user_edit.aspx?id=5,那么这个时候我们就要截取获得user_edit.aspx用来判断,否则,就会出现权限控制不严格的情况,比如列表 /user/user_list.aspx,如果你对访问过来的url没有截取判断,那么访问user_list.aspx?page=5则会通过,但是事实上我们已经控制这个页面不让访问了,就是因为url不同导致权限控制有问题,所以这点一定要注意!
     采用httpModule的好处就是一步操作就可以完成权限控制和未登录验证,效果很好,改变了传统的每个页面都需要判断的写法
    Code:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using System.Collections.Generic;
    using shuang.Model;
    /// <summary>
    ///CheckUserModule 的摘要说明
    /// </summary>
    public class CheckRoleModule : IHttpModule
    {

        public static string loginPage = "login.aspx";
        public CheckRoleModule()
        {
            //
            
    //TODO: 在此处添加构造函数逻辑
            
    //
        }
        #region IHttpModule 成员
        public void Init(HttpApplication context)
        {
            context.AcquireRequestState += new EventHandler(checkUserMenu);
        }

        void checkUserMenu(object sender, EventArgs e)
        {
           
            HttpApplication application = (HttpApplication)sender;          // 获取应用程序            
            string url = HttpContext.Current.Request.Url.ToString();       // 获取Url
            int start = url.LastIndexOf('/') + 1;                             //查找URL中最后一个/的位置
            int end = url.IndexOf('?', start);                                 //查找URL中?位置
            string requestPage = null;
            if (end < 0) end = url.Length;
            requestPage = url.Substring(start, end - start);               //得到所请求的页面
            
    //截取后缀
            if (requestPage == loginPage) return;
            string requestPageSuffix = requestPage.Substring(requestPage.LastIndexOf(".") + 1);
            if (requestPageSuffix != "aspx")
            {
                return;
            }
            string user = OperateCommon.currentUser;//对每一个页面都要判断是否登录
            if (user == null)
            {
                application.Response.Write("<script language='javascript'>parent.location.href='" + Common.ApplicationRootPath + "/login.aspx';</script>");
                return;
            }
            else
            {
               
               
                //查看是否是菜单权限控制页面
                
    //  requestPage = url.Substring(start);
                if (!isProtectedResource(requestPage)) return;
                //检测用户权限
                if (!OperateCommon.isPross(user,requestPage)) {
                    Common.showMsg("0""你没有访问该页面的权限,请联系管理员");
                }
            }
        
            
        }
        /// <summary>
        
    /// 判断页面是否为受权限管理保护的资源
        
    /// </summary>
        
    /// <param name="page">所请求的页面</param>
        
    /// <returns>是否受保护</returns>
        bool isProtectedResource(string page)
        {
           // page = page.ToLower();
            List<String> protectedFiles =OperateCommon.GetMenu();//受保护的页面
            
    //读取所有菜单栏目的url
            bool fig = false;
            foreach (string item in protectedFiles)
            {
                if(item==page)
                {
                    fig = true;
                    break;
                }
            }
            return fig;
        }


        public void Dispose()
        {
           // throw new NotImplementedException();
        }
        #endregion
    }

    OPerateCommon

    View Code
    using System;
    using System.Data;
    using System.Configuration;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using shuang.BLL;
    using shuang.Model;
    using System.Collections.Generic;
    /// <summary>
    ///OperateCommon 的摘要说明
    /// </summary>
    public class OperateCommon
    {
        public OperateCommon()
        {
            //
            
    //TODO: 在此处添加构造函数逻辑
            
    //
        }
        private const string SessionUser = "LoginName";   //登录用户   
        private static string loginName = "";
        public static string currentUser
        {
            get
            {
                if (HttpContext.Current == null)
                {
                    return null;
                }
                else
                {
                    if (HttpContext.Current.Session[SessionUser] != null)
                    {
                        return HttpContext.Current.Session[SessionUser].ToString();
                    }
                }
                return null;
               
            }
            set
            {
                HttpContext.Current.Session[SessionUser] = value;
            }
        }
        public static void getLoginName()
        {
            if (currentUser!= null)
            {
                loginName = HttpContext.Current.Session[SessionUser].ToString();
            }
            else
            {
                HttpContext.Current.Response.Redirect("~/logout.aspx");
            }
        }
        /// <summary>
        
    /// 检测用户的访问权限
        
    /// </summary>
        
    /// <returns></returns>
        public static bool isPross(string loginName,string requestPage)
        {
            UserBLL bll = new UserBLL();
            RoleBLL rolebll = new RoleBLL();
            menuBLL menubll = new menuBLL();
            bool fig = false;
            DataSet ds = bll.GetList(" userName='"+loginName+"'");
            if (ds != null)
            {
                string roleId = ds.Tables[0].Rows[0]["userRole"].ToString();
                Role role = rolebll.GetModel(Convert.ToInt32(roleId));
                string menuId = role.roleMenulimit;
            
                DataSet dsMenu = menubll.GetList(" menuId in("+menuId+")");
                foreach (DataRow row in dsMenu.Tables[0].Rows)
                {
                    string url = row["url"].ToString();
                    int start = url.LastIndexOf('/') + 1;                             //查找URL中最后一个/的位置
                    int end = url.IndexOf('?', start);
                    string url1 = null;
                    if (end < 0) end = url.Length;
                    url1 = url.Substring(start, end - start);
                    if (url1 == requestPage)
                    {
                        fig=true;
                        break;
                    }
                }
            }

            return fig;
        }
        /// <summary>
        
    /// 获取受保护的菜单页面
        
    /// </summary>
        
    /// <returns></returns>
        public static List<string> GetMenu()
        { 
             menuBLL menubll = new menuBLL();
             DataSet ds = menubll.GetList(" parent!=0");
             List<string> menuList = new List<string>();
             foreach (DataRow row in ds.Tables[0].Rows)
             {
                  string url = row["url"].ToString();
                  int start = url.LastIndexOf('/') + 1;//查找URL中最后一个/的位置
                
    //  url = url.Substring(start);
                  int end = url.IndexOf('?', start);  
                  string requestPage = null;
                  if (end < 0) end = url.Length;
                     requestPage = url.Substring(start, end - start);
                     menuList.Add(requestPage);
             }
             return menuList;
        }
    }

    web.config

    <add name="CheckUserModule" type="CheckRoleModule"/>

    这样就完成了权限限制,文件过滤等问题...

  • 相关阅读:
    Git 历史/术语/命令/基本操作
    SQL 术语/语法/基本操作-必知必会
    bootstrap cdn地址
    IDEA 快捷键 大幅提高工作效率
    Django3 模版配置/过滤器/markdown=9
    Django3 路由文件位置/文件格式/路由传值=8
    Django3 创建项目/app全流程=7
    VS Code Django解决不必要报错
    Django3 如何使用静态文件/如何自定义后台管理页面=6
    Django3 如何编写单元测试和全面测试=5
  • 原文地址:https://www.cnblogs.com/shuang121/p/2445216.html
Copyright © 2020-2023  润新知