摘 要
随着教育改革的不断深化,高等院校的建设与发展对国民整体素质的提高起着越来越重要的作用,建立一套能够适应这些改变的行政管理方案也就显得尤为重要。对于教务处来说,将信息技术用于校务管理中便是迫切的要求。
教务系统中的用户数量众多,需要具有不同的权限,以实现不同的应用。本论文介绍了开发背景,开发平台,并基于需求分析实现了教务管理平台中基于角色控制的权限系统(RBAC)及公共模块的设计与开发。RBAC实现了用户与访问权限的逻辑分离,更符合教务平台的用户、数据和应用特征;在公共模块中实现了系统通用的日志管理,异常处理,常用类库方法等。通过设计和应用本系统,有效的解决了教务平台中关于用户管理与权限操作等方面的问题,为系统公共模块的实现打下坚实的基础。通过较为详尽的功能测试,表明本文的设计内容具有一定的通用性,可用于需要动态分配权限与角色的管理系统中。
关键词: 权限;公共模块;RBAC
2.2 开发平台介绍
本毕业设计的命题是教务管理平台中权限系统和公共模块的设计和开发,根据团队要求和开发成本选择了Visual Studio 2005+SQL 2005开发环境,使用的语言为c#。
2.2.1 Visual Studio 2005介绍
Visual Studio 2005 是一系列高效的、智能的开发工具的统称,它拥有一个庞大的产品线,包括面向学生、爱好者、初学者的Express版,面向专家、Visual Basic 6的Standard版,面向顾问、企业开发人员的Professional版和面向架构师的Team System版本。在这些版本中,有些集成了开发软件常用到的东西,比如重构、单元测试、类设计器等等,以方便开发人员快速的设计各类软件。
2.2.2 SQL Server 2005介绍
SQL Server 2005 是一个全面的数据库平台,使用集成的商业智能工具提供了企业级的数据管理。SQL Server 2005 数据库引擎为关系型数据和结构化数据提供了更安全可靠的存储功能,使您可以构建和管理用于业务的高可用和高性能的数据应用程序。SQL Server 2005 数据引擎是企业数据管理解决方案的核心。此外 SQL Server 2005 结合了分析、报表、集成和通知功能。
2.3 开发技术介绍
2.3.1 Asp.net
ASP.NET是微软流行的动态WEB编程技术活动服务器网页(ASP)的最新版本,但它远不是传统ASP简单升级。ASP.NET和ASP的最大区别在于编程思维的转换,ASP.NET是真正的面向对象(Object-oriented),而不仅仅在于功能的增强。
在ASP.NET中,Web 窗体页由两部分组成:视觉元素(HTML、服务器控件和静态文本和该页的编程逻辑。其中每一部分都存储在一个单独的文件中。可视元素在一个扩展名为 .aspx 文件中创建,而代码位于一个单独的类文件中,该文件称作代码隐藏类文件扩展名为.aspx.vb 或 .aspx.cs。这样,.aspx文件中存放所有要显示的元素,aspx.vb或.aspx.cs文件中存放逻辑。
2.3.2 RBAC
企业环境中的访问控制策略一般有三种:自主型访问控制方法、强制型访问控制方法和基于角色的访问控制方法(RBAC)。其中,自主式太弱,强制式太强,二者工作量大,不便于管理。基于角色的访问控制方法是目前公认的解决大型企业的统一资源访问控制的有效方法。其显著的两大特征是:1.减小授权管理的复杂性,降低管理开销;2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。
基于角色的访问控制RBAC作为一种灵活和直观的访问控制技术在20世纪90年代迅速发展起来,RBAC通过引入角色的新概念来实施访问控制策略。不同的角色和它所应具有的权限许可互相联系,用户作为某些角色的成员,获得角色所拥有的权限。角色可以根据实际的单位或组织的不同工作职能和权限来划分,依据用户所承担的不同权利和义务来授权相应的角色,对于一个存在大量用户和权限的权限分配系统来说,从用户到角色的管理,简化了权限分配的复杂性,提高了安全管理的效率和质量。
2.3.3 Identity和IPrincipal
Principal对象是实现了IPrincipal接口的类的实例,这些对象用来表示用户,并且包括了用户的身份信息。
对于每一个线程来说都与一个principal对象相关联。这个principal对象包括了表示运行当前线程的用户的identity对象。
4.2 权限系统模块的实现
系统主功能模块包括用户信息管理,角色管理,权限管理,资源与权限的绑定,用户与角色的绑定等。
4.2.1 用户信息管理和角色绑定
本系统中的起始页面为Login.aspx,如图8所示。
图8 系统登陆界面
用户点击【登录】时,系统初始化命名空间Njj.Accounts.bus下类User的一个user对象,将user赋予当前上下文user对象。根据用户当前的身份标识中的密码验证用户身份的有效性,若成功则设置用户系统登陆,添加日志,添加用户的用户信息到Session中,并且加载用户设置的界面风格,最后跳转到应用系统操作主界面。该程序代码如下所示。
AccountsPrincipal newUser = AccountsPrincipal.ValidateLogin(userName, Password); //根据用户名和密码初始化用户标识,实现iprincipal接口 if (newUser == null) { this.lblMsg.Text = "登陆失败: " + userName; } else { User currentUser = new NJJ.Accounts.Bus.User(newUser);//根据用户标识初始化用户对象 Context.User = newUser; 将当前上下文用户标识设为新用户 if (((SiteIdentity)User.Identity).TestPassword(Password) == 0) //检测用户密码 { this.lblMsg.Text = "你的密码无效!"; } else { FormsAuthentication.SetAuthCookie(userName, false); //设置用户登陆 NJJ.TreeAndLog.TreeAndLogManage log = new NJJ.TreeAndLog.TreeAndLogManage(); log.AddLog(DateTime.Now.ToString(), "用户登陆", User.Identity.Name, "1");//添加日志 Session["UserInfo"] = currentUser; //session保存当前用户信息 Session["Style"] = currentUser.Style; //session保存用户设置的界面风格 if (Session["returnPage"] != null) { string returnpage = Session["returnPage"].ToString(); Session["returnPage"] = null; Response.Redirect(returnpage); } else { Response.Redirect("main.htm"); } } |
用户管理页面为:UserAdmin.aspx,界面如图9所示。
用户角色分配界面如图10所示。
图9 用户管理
图10 角色分配
页面初始化时调用函数user对象的GetAllUsers()方法获取所有用户数据并绑定到datagrid中。
点击图中的修改角色链接可进入用户与角色绑定界面。
4.2.2 角色管理和权限绑定
角色管理和权限绑定页面主要为RoleAdmin.aspx和EditRole.aspx,主要实现对增加新的角色、修改角色、删除角色,和角色对象权限的分配功能。如图11,图12所示。
图11 角色管理
图12 编辑角色信息
RoleAdmin.aspx页面调用了命名空间Njj.Accounts.bus下Role类对象的相关方法,GetRoleList()得到所有的角色列表,Create()建立新角色。
EditRole.aspx中,首先listbox中绑定某类别权限下的所有权限,点击增加权限按钮调用Role类对象的AddPermission()向角色分配对应的权限。
4.2.3 权限管理
权限管理主要实现权限类别及权限命名的管理,如图13所示。代码如下所示。
int CategoryId = int.Parse(this.ClassList.SelectedValue); DataSet PermissionsList = AccountsTool.GetPermissionsByCategory(CategoryId); this.DataGrid1.DataSource = PermissionsList; this.DataGrid1.DataBind(); |
图13 权限管理
本模块包含权限类别的添加,修改,删除,以及类别下子权限的添加,修改,删除等功能,主要针对命名空间下Njj.Accounts.Bus下的PermissionCategories和Permissions类进行操作。
4.2.4 系统资源管理和权限绑定及菜单操作
系统资源管理主页面为:TreeList.aspx和add.aspx,如图14,15所示。
此模块负责添加系统可访问的URL资源和菜单模块的操作。添加菜单时可以和对应的权限相绑定,以动态显示用户菜单。对于对应的URL文件可执行过滤功能,权限不够的用户将拒绝进入。
图14 系统资源管理
图15 添加资源并绑定权限
主要代码如下所示。
NJJ.TreeAndLog.TreeAndLogManage sm = new NJJ.TreeAndLog.TreeAndLogManage(); DataTable dt = sm.GetTreeList("").Tables[0]; this.listTarget.Items.Clear(); //加载菜单选项到下拉列表中 this.listTarget.Items.Add(new ListItem("根目录", "0")); DataRow[] drs = dt.Select("ParentID= " + 0); /循环读取,添加. foreach (DataRow r in drs) { string nodeid = r["NodeID"].ToString(); string text = r["Text"].ToString(); //string parentid=r["ParentID"].ToString(); //string permissionid=r["PermissionID"].ToString(); text = "╋" + text; this.listTarget.Items.Add(new ListItem(text, nodeid)); int sonparentid = int.Parse(nodeid); string blank = "├"; BindNode(sonparentid, dt, blank); } this.listTarget.DataBind(); 绑定父类菜单 /读取所有权限 DataTable tabcategory = NJJ.Accounts.Bus.AccountsTool.GetAllCategories().Tables[0]; int rc = tabcategory.Rows.Count; for (int n = 0; n < rc; n++) { string CategoryID = tabcategory.Rows[n]["CategoryID"].ToString(); string CategoryName = tabcategory.Rows[n]["Description"].ToString(); CategoryName = "╋" + CategoryName; this.listPermission.Items.Add(new ListItem(CategoryName, CategoryID)); ///将权限绑定到下拉列表 DataTable tabforums = NJJ.Accounts.Bus.AccountsTool.GetPermissionsByCategory(int.Parse(CategoryID)).Tables[0]; int fc = tabforums.Rows.Count; for (int m = 0; m < fc; m++) { string ForumID = tabforums.Rows[m]["PermissionID"].ToString(); string ForumName = tabforums.Rows[m]["Description"].ToString(); ForumName = " ├『" + ForumName + "』"; this.listPermission.Items.Add(new ListItem(ForumName, ForumID)); } } this.listPermission.DataBind(); this.listPermission.Items.Insert(0, "--请选择--"); ///绑定权限 |
4.2.5 url过滤
系统对于普通的页面可以判断用户是否有权限来访问,通过继承类System.Web.UI.Page,并自写其中的Page_Load事件,生成公用的Page基类,由于asp.net的代码后置功能,对于web页面来说,判断其所属权限可以通过其后置代码类继承公共的Page基类,来达到代码重用的效果。该程序代码如下所示。
//权限验证 if (Context.User.Identity.IsAuthenticated) ///当前用户是否授权 { AccountsPrincipal user = new AccountsPrincipal(Context.User.Identity.Name); //生成此用户的身份标识 if (Session["UserInfo"] == null) //如果Session保存的用户信息为空,则调用用户信息保存到session,页面重新加载 { NJJ.Accounts.Bus.User currentUser = new NJJ.Accounts.Bus.User(user); Session["UserInfo"] = currentUser; Session["Style"] = currentUser.Style; Response.Write("<script defer>location.reload();</script>");
} Permissions p = new Permissions(); ///session保存的用户信息不为空,调用权限表 PermissionID=p.GetPermissionID(Request.FilePath.Substring(24).Trim()); /// 获取url请求
if ((PermissionID != -1) && (!user.HasPermissionID(PermissionID))) 如果页面不为公共页面的话,则调用此页面的权限ID来判断用户是否有此权限 { Response.Clear(); Response.Write("<script defer>window.alert('您没有权限进入本页!\\n请重新登录或与管理员联系');history.back();</script>"); ///用户无权限,则重新登陆 Response.End(); } } else { FormsAuthentication.SignOut(); ///用户没有授权的话,将注销用户。 Session.Clear(); Session.Abandon(); Response.Clear(); Response.Write("<script defer>window.alert('您没有权限进入本页或当前登录用户已过期!\\n请重新登录或与管理员联系!');parent.location='" + virtualPath + "/Login.aspx';</script>"); Response.End(); } |