转载: http://www.comprg.com.cn/post_show.asp?id=7873
作者:佚名
一、引言
随着.NET
和J2EE
开发平台的推出,传统的软件开发模式开始向B/S
模式转变,这种转变给系统的安全性提出了更高的要求,B/S
模式下,由于HTTP
协议和浏览器的特殊性,可能会造成信息的泄漏甚至使非法用户修改数据。而权限的设置、分配与管理是任何一个系统必不可少的功能。如何设计与实现其功能,目前有多种方案,传统的访问控制方法DAC
(Discretionary Access Control
,自主访问控制模型)、MAC
(Mandatory Access Control
,强制访问控制模型)难以满足复杂的企业环境需求。本文采用了现在流行的基于角色访问控制(RBAC
,Role Based Access Control
)的基本思想,巧妙地利用了Web
控件TreeView
及ASP.NET
技术,设计了在B/S
模式下,根据不同的用户,不同的角色权限,动态生成用户菜单树的一种具体实现方法。
本文将先介绍RBAC
的基本思想,在此基础上,给出在ASP.NET
中的具体实现方法。
二、角色访问控制(RBAC)的基本思想
图1
RBAC
的基本思想
在RBAC
中,许可Permissions
(特权)就是允许对一个或多个客体执行的权力,角色就是许可的集合,如图1
所示。RBAC
的基本思想就是把整个访问过程分为两步:访问权限与角色关联,角色再与用户关联,从而实现了用户与访问权限的逻辑分离。
RBAC
对访问权限的授权由系统管理员统一管理,系统管理员根据单位中不同的岗位定义不同的角色,用户根据其职能和责任被赋予相应的角色。一旦用户成为某角色的成员,则此用户可以完成该角色所具有的职能。
由于RBAC
实现了用户与访问权限的逻辑分离,因此它极大地方便了权限管理的复杂性。可根据用户的实际工作岗位将用户与角色关联,一方面定义角色、增加删除角色中的用户易于操作,另一方面,可以通过更改角色的权限实现大批量用户权限的更新。在实际应用中,由于角色/
权限之间的变化比用户/
角色之间的变化要慢得多,当一个用户的职位发生了变化,只要将用户当前的角色去掉,加入代表新职务的角色即可。因此,RBAC
的优点是明显的,更符合企业的应用特征。
三、用户权限菜单树
用TreeView
控件动态实现用户权限菜单树的基本思想是:根据角色访问控制(RBAC
)的基本原理,给用户分配不同的角色,每个角色对应一些权限,然后根据用户ID
获取用户对应的角色集合,由角色集合获取对应的权限集合,再由权限集合利用TreeWiew
控件动态生成一棵由该用户对应的角色能访问的页面(模块)组成的权限树。这样,用户无权访问的页面在权限菜单树就不会出现,不同的用户进入的界面不同,实现了用户权限的统一管理。
下面从功能模块设计、数据库设计、架构设计等几方面来阐述其实现过程。
1
.功能模块划分
图2
用户权限管理功能模块图
用户权限管理系统功能如图2
所示,其中主要模块功能阐述如下:
用户管理模块分为:删除用户、浏览用户和角色分配三个子模块,主要负责各类用户的删除、合法性验证及为用户分配角色。用户管理模块中并没有增加用户子模块的功能,主要是由用户注册模块来实现的。
权限管理模块分为:角色管理和访问控制两个子模块。角色管理负责管理各类角色(增、删、改),为角色授予相应信息服务模块的使用权限,删除角色的某个模块的
使用权限等;访问控制是保证信息安全的关键,用户登录时经身份验证后,系统根据用户具有角色的信息服务模块的使用权限自动生成访问权限集,使得用户能够访
问授权的信息,拦截对没有授权信息服务的访问。
2.
数据库设计
在实施RBAC
生成用户权限菜单树时,为了提高系统管理及数据访问的效率,在数据库中设计了用户表(表1
所示)、角色表(表2
所示)、用户角色表(表3
所示)、角色权限表(表4
所示)及菜单树结构表(表5
所示)共5
个表。
表1
用户信息表Users
字段名
|
类型
|
字段中文名
|
UserID
|
int
|
用户ID
主键
|
UserName
|
Varchar(50)
|
用户名
|
Password
|
Varchar(100)
|
用户密码
用MD5
加密
|
RealName
|
Varchar(50)
|
用户真实姓名
|
Email
|
Varchar(100)
|
用户Email
|
State
|
int
|
用户状态,默认:0
|
Baoliu
|
Char(1)
|
保留,默认:1
|
表2
角色信息表Roles
字段名
|
类型
|
字段中文名
|
RoleID
|
int
|
角色ID
主键
|
RoleName
|
Varchar(20)
|
角色名称
用MD5
加密
|
RoleDesc
|
Varchar(50)
|
角色描述
|
PerMission
|
Varchar(50)
|
角色权限
|
Baoliu
|
Char(1)
|
保留,默认:1
|
表3
用户角色表UserRoles
字段名
|
类型
|
字段中文名
|
RoleID
|
int
|
角色ID
|
UserID
|
int
|
用户ID
|
表4
角色权限表RolePermissions
字段名
|
类型
|
字段中文名
|
RoleID
|
int
|
角色ID
|
TreeID
|
int
|
菜单ID
|
ParentID
|
Int
|
父菜单ID
|
表5
菜单树结构表Tree
字段名
|
类型
|
字段中文名
|
TreeID
|
int
|
菜单ID
主键
|
Title
|
Varchar(200)
|
菜单标题
|
Desn
|
Text(16)
|
菜单描述
|
ParentID
|
Int(4)
|
菜单父ID
|
Url
|
Varchar(200)
|
菜单链接地址
|
Web
程序中,将系统功能模块组织成树型结构,每个模块对应一个菜单,菜单之间的父子关系直接反映了模块之间的父子关系,在数据库中用一张表Tree
来存储这种结构。
5
个表的关系如图3
所示。
图3
5
个表之间的关系图
3.
系统架构设计
B/S
模式下,采用三层结构:表示层、逻辑层及数据层。为了编程方便,把数据层分为实体层和数据访问层,把打开、关闭数据库及调用存储过程的代码全部封将在数据访问类SQLHelper.cs
中。实际应用中采用的是四层结构,系统架构设计如图4
所示。
图4
用户权限管理架构图
注:图4
中的箭头为调用关系。
为了提高程序的执行效率,所有的数据操作都是通过类SQLHelper.cs
调用存储过程来实现的。
实体层的几个主要类及关键方法如下:
(1
)用户类User
:
GetUserLogin(string sUserName,string sPassword)
:用户登录验证。
GetRoleByUser(int nUserID)
:由用户ID
返回该用户所有的角色集。
AddUserRole(int nUserID,int nRoleID):
为用户分配角色。
GetUserPermissionList( int userID )
:得到用户的所有权限集。
(2
)角色类RoleEntity
:
AddRoleModule(int nTreeID,int nRoleID)
:为角色分配权限。
DeleteRoleModule(int nRoleID)
:删除角色拥有的权限。
GetModuleByRole(int nRoleID)
:由角色ID
得到该角色的权限集。
(3
)权限树类Tree
:
BindTree(TreeView treeView,int userID):
生成树目录。
CreateChildNode(TreeNode parentnode,DataTable dataTable)
:递归函数生成树结点。
GetTreesByUserID(int nUserID)
:由用户ID
得到用户权限集动态生成用户权限树。
(4
)用户权限检查类CkeckAuthority
:
ChkPermission( int userID )
:检查用户是否有访问权限。
IsInRole(int roleID)
:检查角色是否存在。
4
.具体实现
在树型结构中,给角色授权时采取简单方式,每次授权时,将其对应的RoleID
、TreeID
及ParentID
存入RolePermissions
表中,见图5
。
图5
角色授权
要实现动态生成用户菜单树,在ASP.NET
开发环境中必须安装微软的IE
Web
控件(可到微软的网站免费下载),安装完成后,在开发环境中引用Microsoft.Web.UI.WebControls.dll
,这样在开发环境的工具箱中将会出现MutiPage
、TabStrip
、Toobar
和TreeView
等IE
Web
控件。
将IE
Web
控件TreeView
添加到Web
页分以下两步:
(1
)在页面顶端添加以下@Register
指令:
<%@Register TagPrefix=”iewc”
Namespace=” Microsoft.Web.UI.WebControls”
Assembly=” Microsoft.Web.UI.WebControls” %>
(2
)在Web
页中需显示TreeView
的位置添加以下Web
控件语法:
<iewc:TreeView runat=”server” …>
…
</ iewc:TreeView>
关于TreeView
控件的用法,读者可参看相应的书籍。
总体架构页面包括用户登录(Longin.aspx
)和主界面(Default.aspx
)两个部分。
主界面分为三个部分:上部分为标题条(Head.aspx)
,左部分为菜单目录树(LeftTree.aspx
),右部分主框架(MainFram.aspx
)。其中LeftTree.aspx
页面含TreeView
控件,用户单击树中的菜单结点就可打开相应的操作页面。
用户登录采用窗体式验证,负责提供用户的身份验证。然后根据用户在系统中所扮演的角色,取出该用户对应的权限集,动态生成该用户对应本系统的操作权限树(见图6
)。
图6
用户访问权限示意图
登录体Login.aspx
中的主要代码如下:
private void LoginBtn_Click(object sender, System.EventArgs e)
{
if(Page.IsValid == true)
{
Entity.User user=new User();
string userId = "";
string isValid=""; //用户的合法标志
//用户身份鉴别
SqlDataReader recs = user.GetUserLogin(UserName.Text.Trim(),
Entity.User.Encrypt(Password.Text.Trim()));
if(recs.Read())
{
userId = recs["UserID"].ToString();
//取到用户的合法标志
isValid=recs["State"].ToString();
}
recs.Close();
if(isValid=="0") //用户没有被系统管理同确定,转向访问拒绝面
{Response.Redirect("AccessDenied.aspx");}
if((userId != null) && (userId != ""))
{ Session["UserID"] =userId;
Entity.CkeckAuthority chkau=
new CkeckAuthority();
//用户访问权限检验
if(!chkau.ChkPermission(Int32.Parse
(Session["UserID"].ToString())))
{ // 如无权限直接转向访问拒绝面Response.Redirect("AccessDenied.aspx");}
else
{//用户有访问权限,创建用户名,密码验证的票据
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket(
1, // version 版本
UserName.Text.Trim(), // 用户cookie名
DateTime.Now, // 发布日期
DateTime.Now.AddHours(1),//过期日期
false, //cookie 持久性(false)
Password.Text.Trim() // 用户密码
);
// 加密票据
String cookieStr = FormsAuthentication.Encrypt(ticket);
// 将存有用户名、密码信息的字符串存入cookie
Response.Cookies["userticket"].Value = cookieStr;
Response.Cookies["userticket"].Path = "/";
Response.Cookies["userticket"].Expires = DateTime.Now.AddMinutes(1);
//跳转到由用户权限动态生成的主页面Response.Redirect("Default.aspx"); }
}
else
{ UserName.Text = "";
Password.Text = "";
Message.Text = "你输入的用户名称或者密码有误,请重新输入!";
}
}
}
LeftTree.aspx中的主要代码如下:
private void Page_Load(object sender, System.EventArgs e)
{ …
if(!Page.IsPostBack)
{ // 实例化一个树对象
Tree tree = new Tree();
//动态创建树型菜单,参数ModuleTview为TreewView控件对象
tree.BindTree(ModuleTview,Int32.Parse(Session["UserID"].ToString()));
…}
}
此外,为了防止非法用户直接绕过登录验证窗体而在网址中直接输入访问路径进行非法访问,利用ASP.NET
中的用户控件,直接将票据验证、角色验证封装在用户控件CheckUserAuth.ascx
中,在每一个受控的页面中加入用户控件CheckUserAuth.ascx
,若为非法用户直接转向拒绝访问页AccessDenied.aspx
,这样使得系统更加安全可靠。有关Web.config
中基于Forms
验证的配置方法,本文不再赘述。
运行效果:
角色分别为成绩管理员和系统管理员的菜单树如图7
和图8
所示。
图7
角色为成绩管理员的菜单树
图8
角色为系统管理员的菜单树
四、结语
在B/S
模式下,信息系统的安全设计有了新的需求,相对于传统的C/S
应用程序,B/S
应用程序对安全性提出了更高的要求,不但要考虑数据访问的安全性,还要考虑网络的安全性。
本文以RBAC
的思想,采用多层架构,利用TreeView
控件及ASP.NET
技术,设计了一个根据不同的用户不同的角色权限,动态生成用户权限树的方法,该方法高效、安全,用户只能操作有权限的模块,无权限的模块对用户不可见,不同的用户所进入的界面不同,提高了系统的安全性和可靠性。利用本文的方法,可以迅速构建一个安全、高效的B/S
方式管理信息系统。
笔者用微软的Visual Studio.NET
作为开发平台,SQL Server
作为数据库,按照本文的方法开发了一套综合管理信息系统,在应用中取得良好的效果。
分享到:
相关推荐
【角色访问动态生成用户权限菜单树】是一种在B/S(Browser/Server,浏览器/服务器)模式下实现权限管理的方法,特别是在.NET和J2EE开发环境中。传统的访问控制模型,如DAC(自主访问控制)和MAC(强制访问控制),在...
动态生成菜单树的一个关键特性是根据用户角色和权限展示适当的菜单。这需要在后端处理数据时进行过滤,只将用户有权访问的菜单项传递给前端。 7. 性能优化: 当菜单数量庞大时,为避免一次性加载导致性能下降,...
在C# WinForm应用开发中,权限控制是一个关键的安全组件,它确保了只有授权的用户才能访问特定的功能或数据。本教程将详细讲解如何在C# WinForm环境中实现基于角色的权限控制,包括角色、用户和权限的设置。 首先,...
- **菜单权限控制**:根据用户角色动态生成显示的菜单,隐藏无权访问的功能。 - **按钮权限控制**:针对具体操作,如添加、删除、修改等,控制按钮的可见性和可用性。 - **数据过滤**:在数据列表展示时,根据用户...
这一步通常包括用户表、角色表、权限表等,这些表之间的关系设计反映了系统的权限模型,如用户角色关联、角色权限关联等。数据库的设计是权限管理系统的核心,因为它定义了谁可以访问哪些资源。 在运行项目之前,...
这种动态菜单生成基于用户角色的权限信息,提高了系统的安全性和用户体验。 5. **数据库结构**: 为了实现这一功能,通常需要设计一个数据库来存储角色、用户、权限之间的关系。可能包含以下表:`Users`(用户)、...
本篇文章将详细探讨如何在SpringBoot中实现基于RBAC(Role-Based Access Control,基于角色的访问控制)的权限控制,包括菜单控制、页面元素控制以及URL控制。 首先,让我们理解RBAC模型。RBAC是一种权限分配策略,...
在这个示例中,菜单项的`Tag`属性通常用来存储权限标识,这样就可以根据用户角色来决定其可见性。 5. **事件驱动编程**:为了响应用户登录和角色改变,我们需要监听相应的事件,比如`AuthenticationStatusChanged`...
在这个场景下,"java动态生成菜单"的实现通常基于用户角色权限来确定用户可见的菜单项,确保安全性和定制化。`dtree`插件则是一个用于前端展示的树形结构组件,它可以优雅地展示这些动态生成的菜单。 首先,我们...
动态菜单基于用户的权限、角色或特定条件进行生成,使得用户界面更加灵活和定制化。下面我们将深入探讨这个话题。 首先,动态菜单的核心在于“动态”二字。这意味着菜单项不是静态固定的,而是根据用户登录状态、...
综上所述,从数据库中读出数据动态生成menu菜单栏是一个涉及数据库操作、后端逻辑处理、前端展示和用户权限控制的复杂过程。在实际开发中,应确保数据安全,优化性能,并且提供良好的用户体验。通过合理的设计和实现...
在C# WinForm应用开发中,基于角色的权限管理是一个重要的功能,它允许系统管理员根据不同的用户角色分配不同的操作权限,以确保数据安全和系统稳定性。本完整的源码实现了一个通用的权限管理系统,适用于二次开发,...
这意味着开发者可以利用代码在运行时创建和布局菜单项,根据用户角色或权限动态显示或隐藏某些菜单,以适应不同的访问级别。 使用UserControl来动态生成父子菜单的好处在于: 1. **灵活性**:可以根据需要动态添加...
在IT行业中,构建一个动态树形权限菜单是常见的需求,特别是在开发管理后台或者Web应用程序时。这个主题聚焦于使用Java后端与JavaScript前端,结合SqlServer2005数据库来实现这样的功能。以下将详细讲解这一技术栈中...
动态生成菜单的过程包括从数据库查询用户的角色和相应的操作权限,然后根据这些信息构建菜单结构。 VCLSkin控件是这个过程中的一个重要工具,它不仅提供了丰富的皮肤样式,还能与Delphi的其他组件无缝集成。在动态...
在IT行业中,动态生成的树型导航菜单是一种常见的前端交互设计,它能够根据后端数据库中的数据自动生成,为用户提供直观、高效的导航体验。本文将深入探讨如何实现这样的功能,并结合给定的“树菜单”文件,分析其...
2. 开发后台逻辑:编写C#或VB.NET代码,实现用户登录验证,获取用户角色,以及根据角色加载权限菜单。 3. 创建ASP.NET页面:使用ASP.NET控件如TreeView,结合JavaScript进行交互设计,使菜单能够动态加载和响应用户...
总结一下,"权限菜单树"是Web应用中一种常见的权限管理方式,它利用树形结构展示用户权限,增强了用户体验,也保障了系统安全。EXT库提供了一个强大的TreePanel组件,使得在JavaScript环境中实现权限菜单树变得简单...
5. **前端展示**:前端可能使用Vue、React或Angular等前端框架,通过Ajax请求获取权限菜单,根据用户角色动态渲染菜单栏。 **安全性考虑** 1. **防止CSRF攻击**:Shiro提供跨站请求伪造(CSRF)防护,可以通过添加...
在这个场景中,我们关注的是如何利用Shiro实现根据用户权限动态显示不同的菜单。 首先,理解Shiro的核心概念是关键。在Shiro中,权限分为角色(Role)和权限(Permission)。角色是一组权限的集合,权限则具体描述...