基于权限控制的菜单如何设计

angel99 2003-08-20 05:27:02
我想通过数据库的权限控制,来设计菜单系统。使得不同用户显示的菜单不同,不知如何实现?有具体例子吗?这个问题困扰我快一个月了,哪位高手愿好心相助!急盼
...全文
637 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
nchen123 2003-12-02
  • 打赏
  • 举报
回复
http://expert.csdn.net/Expert/topic/1653/1653829.xml?temp=.7213251
wanddy 2003-12-02
  • 打赏
  • 举报
回复
仔细阅读吧!
但凡涉及多用户不同权限的网络或者单机程序,都会有权限管理的问题,比较突出的是MIS系统。

下面我要说的是MIS系统权限管理的数据库设计及实现,当然,这些思路也可以推广开来应用,比如说在BBS中用来管理不同级别的用户权限。

权限设计通常包括数据库设计、应用程序接口(API)设计、程序实现三个部分。

这三个部分相互依存,密不可分,要实现完善的权限管理体系,必须考虑到每一个环节可行性与复杂程度甚至执行效率。

我们将权限分类,首先是针对数据存取的权限,通常有录入、浏览、修改、删除四种,其次是功能,它可以包括例如统计等所有非直接数据存取操作,另外,我们还可能对一些关键数据表某些字段的存取进行限制。除此,我想不出还有另外种类的权限类别。

完善的权限设计应该具有充分的可扩展性,也就是说,系统增加了新的其它功能不应该对整个权限管理体系带来较大的变化,要达到这个目的,首先是数据库设计合理,其次是应用程序接口规范。

我们先讨论数据库设计。通常我们使用关系数据库,这里不讨论基于Lotus产品的权限管理。

权限表及相关内容大体可以用六个表来描述,如下:
1 角色(即用户组)表:包括三个字段,ID,角色名,对该角色的描述;
2 用户表:包括三个或以上字段,ID,用户名,对该用户的描述,其它(如地址、电话等信息);
3 角色-用户对应表:该表记录用户与角色之间的对应关系,一个用户可以隶属于多个角色,一个角色组也可拥有多个用户。包括三个字段,ID,角色ID,用户ID;
4 限制内容列表:该表记录所有需要加以权限区分限制的数据表、功能和字段等内容及其描述,包括三个字段,ID,名称,描述;
5 权限列表:该表记录所有要加以控制的权限,如录入、修改、删除、执行等,也包括三个字段,ID,名称,描述;
6 权限-角色-用户对应表:一般情况下,我们对角色/用户所拥有的权限做如下规定,角色拥有明令允许的权限,其它一律禁止,用户继承所属角色的全部权限,在此范围内的权限除明令禁止外全部允许,范围外权限除明令允许外全部禁止。该表的设计是权限管理的重点,设计的思路也很多,可以说各有千秋,不能生搬硬套说某种方法好。对此,我的看法是就个人情况,找自己觉得合适能解决问题的用。

先说第一种也是最容易理解的方法,设计五个字段:ID,限制内容ID,权限ID,角色/用户类型(布尔型字段,用来描述一条记录记录的是角色权限还是用户权限),角色/用户ID,权限类型(布尔型字段,用来描述一条记录表示允许还是禁止)

好了,有这六个表,根据表六,我们就可以知道某个角色/用户到底拥有/禁止某种权限。

或者说,这么设计已经足够了,我们完全实现了所需要的功能:可以对角色和用户分别进行权限定制,也具有相当的可扩展性,比如说增加了新功能,我们只需要添加一条或者几条记录就可以,同时应用程序接口也无须改动,具有相当的可行性。但是,在程序实现的过程中,我们发现,使用这种方法并不是十分科学,例如浏览某个用户所拥有的权限时,需要对数据库进行多次(甚至是递归)查询,极不方便。于是我们需要想其它的办法。使用过Unix系统的人们都知道,Unix文件系统将对文件的操作权限分为三种:读、写和执行,分别用1、2、4三个代码标识,对用户同时具有读写权限的文件被记录为3,即1+2。我们也可以用类似的办法来解决这个问题。初步的想法是修改权限列表,加入一个字段:标识码,例如,我们可以将录入权限标识为1,浏览权限标识为2,修改权限标识为4,删除权限标识为8,执行权限标识为16,这样,我们通过权限累加的办法就可以轻易的将原本要分为几条记录描述的权限放在一起了,例如,假定某用户ID为1,库存表对应的限制内容ID为2,同时规定角色类型为0、用户类型为1,我们就可以将该用户具有录入、浏览、修改、删除库存表的权限描述为:2,15,1,1。

确实很简单,不是吗?甚至还有更过激的办法,将限制内容列表也加上一列,定义好标识码,这样,我们甚至可以用简单的一条记录描述某个用户具有的对全部内容所具有的全部权限了。当然,这样做的前提是限制内容数量比较小,不然,呵呵,2的n次方递增起来可是数量惊人,不容易解析的。

从表面上看,上述方法足以达到实现功能、简化数据库设计及实现的复杂度这个目的,但这样做有个弊端,我们所涉及的权限列表不是相互独立而是互相依赖的,比如说修改权限,其实是包含浏览权限的,例如,我们可能只是简单的设置用户对库存表存取的权限值为录入+修改+删除(1+4+8=13),但事实上,该用户具有(1+2+4+8=15)的权限,也就是说,在这种方案中,13=15。于是当我们调用API询问某用户是否具有浏览权限时,就必须判断该用户是否具有对该数据表的修改权限,因此,如果不能在程序中固化权限之间的包含关系,就不能利用应用程序接口简单的做出判断。但这与我们的目的“充分的可扩展性”矛盾。

这个问题如何解决?我想到了另外一种设置标识码的方法,那就是利用素数。我们不妨将录入、浏览、修改、删除、执行的基本标志码定为2,3,5,7,11,当遇到权限互相包含的时候,我们将它的标识码设定为两个(或多个)基本标志码的乘积,例如,可以将“修改”功能的标志码定为3*5=15,然后将所有的权限相乘,就得到了我们需要的最终权限标识值。这样,我们在询问用户是否具有某项权限的时候,只需要将最终的值分解成质因子,例如,我们可以定义一个用户具有录入+修改+删除库存表的权限为 2*15*7=2*3*5*7,即表示,该用户具有了对库存表录入+浏览+修改+删除权限。

当然,对权限列表我们使用上述方法的前提是权限列表记录条数不会太多并且关系不是十分复杂,否则,光是解析权限代码就要机器忽悠半宿:)

我希望以上的分析是正确且有效的
wanddy 2003-12-01
  • 打赏
  • 举报
回复
实现基于角色的安全性:

建立角色和映射用户
用户到角色的映射可以存储在 Active Directory、SQL Server 表等数据存储区中。余下的步骤假定角色是从 SQL Server 数据库中提取的。
在运行时分配角色
当用户登录时,应用程序从数据库或目录服务中查找角色。然后将角色放置在 FormsAuthenticationTicket 中以避免后面对数据存储区的请求,从而提高性能。角色分配在以下代码中进行演示,这可在成功进行身份验证之后,在登录页后面的代码中实现。角色是一个帮助器类(在此未显示),当调用构造函数时,它从角色数据库中提取角色并将它们放置到内部角色数组中。由于我们正在身份验证票中将角色存储为字符串,因此类的 ToString 方法将数组转换为字符串表示形式。在此示例中,角色帮助器类接受三个参数:已验证身份的用户、应用程序名称和到包含角色的数据库的连接字符串。
HttpContext currentContext = HttpContext.Current;
string formsCookieStr = string.Empty;
Roles userRoles = new Roles(UserId,SFConfig.ApplicationName,SFConfig.RoleDBConnString);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // version
UserId, // user name
DateTime.Now, // issue time
DateTime.Now.AddMinutes(30), // expires
false, // persistent
userRoles.ToString() // user data
);

// get the encrypted representation suitable for placing in a HTTP cookie
formsCookieStr = FormsAuthentication.Encrypt(ticket);
HttpCookie FormsCookie = new HttpCookie(FormsAuthentication.FormsCookieName, formsCookieStr);
currentContext.Response.Cookies.Add(FormsCookie);
用户后面提交的请求将在请求标题中包含身份验证票,而服务器上的运行库将基于已登录用户的详细信息创建身份和用户。然而,并不会自动提取和分配添加到身份验证票的角色。要使用适当的用户角色设置用户,需要在下面的步骤中描述的运行线程上创建一个新用户并进行替换。

用户替换
用户对象表示代码所运行的安全上下文。实现基于角色的安全性的应用程序将基于与用户对象关联的角色来授予权限。若要设置每次请求时与用户关联的角色,在此实现中,应在 Global.asax 的 Application_OnAuthenticationRequest 函数中替换用户,如下所示:
protected void Application_OnAuthenticateRequest(Object src, EventArgs e)
{
HttpContext currentContext = HttpContext.Current;
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if( HttpContext.Current.User.Identity is FormsIdentity )
{
FormsIdentity id = HttpContext.Current.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
// Roles is a helper class which places the roles of the
// currently logged on user into a string array
// accessable via the value property.
Roles userRoles = new Roles(userData);
HttpContext.Current.User = new GenericPrincipal(id, userRoles.Value);
}
}
}
}
检查角色成员
现在用户的角色已在线程的当前用户中可用,代码可以使用此角色信息来允许或拒绝对某些功能的访问。这可以通过以下的三种方式之一来实现:
代码的属性。

[PrincipalPermissionAttribute(SecurityAction.Demand, Role = "MyRole")]
IsInRole 方法调用

使用用户的 IsInRole 方法以编程方式评估角色成员。

Web.Config

修改 Web.Config 文件,根据角色成员关系允许或拒绝对页的访问,如下所示:

<authorization>
<allow users="comma-separated list of users"
roles="comma-separated list of roles"
verbs="comma-separated list of verbs" />

<deny users="comma-separated list of users"
roles="comma-separated list of roles"
verbs="comma-separated list of verbs" />
</authorization>
wanddy 2003-12-01
  • 打赏
  • 举报
回复
谁给出一个在VB中实现ROLE的例子,CS里有一个,我没有试过
在数据库中有一表,
username userrole
user1 users
user2 users
user3 administrators

然后在登陆验证中创造凭据,然后在web.config能控制访问就行,
目录结构 web.config中相应的行
\approot
├accessbyuser <alow role="users" deny role="administrators"/>
┝accessbyadmin <alow role="administrators" deny role="users"/>
┗accessbyallusers <deny user="?"/>
zxggwan 2003-12-01
  • 打赏
  • 举报
回复
up
lanyahuhu 2003-11-13
  • 打赏
  • 举报
回复
我也不知道
bpy 2003-11-13
  • 打赏
  • 举报
回复
gz
inethax 2003-11-07
  • 打赏
  • 举报
回复
up
SnApnet 2003-10-11
  • 打赏
  • 举报
回复
学习,思考
jiangzhu 2003-10-11
  • 打赏
  • 举报
回复
架构不同权限的菜单,不同权限的用户访问挂靠不同的菜单.
bpy 2003-09-27
  • 打赏
  • 举报
回复
gz
cm8983 2003-08-21
  • 打赏
  • 举报
回复
ASPMENU1.1可以用dataset,不一定用xml,关键是你要取的数据集
简单的例子:
取到dataset
Dim newItem As CYBERAKT.WebControls.Navigation.MenuItem
Dim newGroup As CYBERAKT.WebControls.Navigation.MenuGroup
Dim rROOT, cROOT As DataRow
'With aspMenu '设置显示样式
' .ImagesBaseURL = "images/"
' .DefaultItemSpacing = "0"
' .DefaultGroupCssClass = "MenuGroup"
' .DefaultItemCssClass = "MenuItem"
' .DefaultItemCssClassOver = "MenuItemOver"
' .DefaultItemCssClassDown = "MenuItemDown"
'End With
For Each rROOT In dsROOT.Tables(0).Rows
'增加根目录
newItem = aspMenu.TopGroup.Items.Add()
newItem.Label = rROOT("MC").ToString() '根目录显示名称
newGroup = newItem.AddSubGroup()
For Each cROOT In dsROOT.Tables(0).Rows
''增加子目录
newItem = newGroup.Items.Add()
newItem.Label = cROOT("MC").ToString() '子目录显示名称
newItem.ID = cROOT("URL").ToString() '子目录连接地址
Next
Next
angel99 2003-08-21
  • 打赏
  • 举报
回复
感谢楼上的各位,我是在WEB程序中,利用微软提供的ASPMENU组件来设计菜单,它的菜单内容是通过XML文件来取的,我现在困惑的是如何利用该组件,但又像WINDOWS程序一样控制菜单权限。
linyoung 2003-08-21
  • 打赏
  • 举报
回复
up
stpangpang 2003-08-21
  • 打赏
  • 举报
回复
学习,我写的东西 原来是用菜单,但是由于权限的问题,我换成 trerview 加 框架网 了
cm8983 2003-08-21
  • 打赏
  • 举报
回复
>>>那从dataset中读出来显示menu 的代码何时如何执行?aspMenu的属性和方法哪里可以查到?

我是在验证用户密码时,验证通过后根据该脚色来生成dataset,当然要有一个表来管理你的
全部页面.根据用户脚色,部门,页面管理表等数据表来生成dataset.
vbdelphi 2003-08-21
  • 打赏
  • 举报
回复
权限设计(初稿)
1. 前言:
权限管理往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断“Who对What(Which)进行How的操作”的逻辑表达式是否为真。针对不同的应用,需要根据项目的实际情况和具体架构,在维护性、灵活性、完整性等N多个方案之间比较权衡,选择符合的方案。
2. 目标:
直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重要简单,包括概念数量上的简单和意义上的简单还有功能上的简单。想用一个权限系统解决所有的权限问题是不现实的。设计中将常常变化的“定制”特点比较强的部分判断为业务逻辑,而将常常相同的“通用”特点比较强的部分判断为权限逻辑就是基于这样的思路。
3. 现状:
对于在企业环境中的访问控制方法,一般有三种:
1.自主型访问控制方法:目前在我国的大多数的信息系统中的访问控制模块中基本是借助于自主型访问控制方法中的访问控制列表(ACLs)。
2.强制型访问控制方法:用于多层次安全级别的军事应用。
3.基于角色的访问控制方法(RBAC):是目前公认的解决大型企业的统一资源访问控制的有效方法。其显著的两大特征是:1.减小授权管理的复杂性,降低管理开销。2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。
4. 名词:
粗粒度:表示类别级,即仅考虑对象的类别(the type of object),不考虑对象的某个特定实例。比如,用户管理中,创建、删除,对所有的用户都一视同仁,并不区分操作的具体对象实例。
细粒度:表示实例级,即需要考虑具体对象的实例(the instance of object),当然,细粒度是在考虑粗粒度的对象类别之后才再考虑特定实例。比如,合同管理中,列表、删除,需要区分该合同实例是否为当前用户所创建。
5. 原则:
权限逻辑配合业务逻辑。即权限系统以为业务逻辑提供服务为目标。相当多细粒度的权限问题因其极其独特而不具通用意义,它们也能被理解为是“业务逻辑”的一部分。比如,要求:“合同资源只能被它的创建者删除,与创建者同组的用户可以修改,所有的用户能够浏览”。这既可以认为是一个细粒度的权限问题,也可以认为是一个业务逻辑问题。在这里它是业务逻辑问题,在整个权限系统的架构设计之中不予过多考虑。当然,权限系统的架构也必须要能支持这样的控制判断。或者说,系统提供足够多但不是完全的控制能力。即,设计原则归结为:“系统只提供粗粒度的权限,细粒度的权限被认为是业务逻辑的职责”。
权限公式:Who+What(Which)+How 的问题,在这里我们实现What和部分Which的权限问题(粗粒度和细粒度相合,到一定的程度),其他的权限问题留给业务逻辑解决
6. 概念:
Who:权限的拥用者或主体(Principal(负责人)、User、Group、Role、Actor等等)
What:权限针对的对象或资源(Resource、Class)。
How:具体的权限(Privilege, 正向授权与负向授权)。
Role:是角色,拥有一定数量的权限。
Operator:操作。表明对What的How 操作。
7. 解释:
User:与 Role 相关,用户仅仅是纯粹的用户,权限是被分离出去了的。User是不能与 Privilege 直接相关的,User 要拥有对某种资源的权限,必须通过Role去关联。解决 Who 的问题。
Resource:就是系统的资源,比如部门新闻,文档等各种可以被提供给用户访问的对象。
Privilege:是Resource Related的权限。就是指,这个权限是绑定在特定的资源实例上的。比如说部门新闻的发布权限,叫做"部门新闻发布权限"。这就表明,该Privilege是一个发布权限,而且是针对部门新闻这种资源的一种发布权限。Privilege是由Creator在做开发时就确定的。Privilege 如"删除" 是一个抽象的名词,当它不与任何具体的 Object 或 Resource 绑定在一起时是没有任何意义的。拿新闻发布来说,发布是一种权限,但是只说发布它是毫无意义的。因为不知道发布可以操作的对象是什么。只有当发布与新闻结合在一起时,才会产生真正的 Privilege。这就是 Privilege Instance。
Role:是粗粒度和细粒度(业务逻辑)的接口,一个基于粗粒度控制的权限框架软件,对外的接口应该是Role,具体业务实现可以直接继承或拓展丰富Role的内容,Role不是如同User或Group的具体实体,它是接口概念,抽象的通称。
Operator的定义包括了Resource Type和Method概念。即,What和How的概念。之所以将What和How绑定在一起作为一个Operator概念而不是分开建模再建立关联,这是因为很多的How对于某What才有意义。比如,发布操作对新闻对象才有意义,对用户对象则没有意义。
8. 思想:
权限系统的核心由以下三部分构成:1.创造权限,2.分配权限,3.使用权限,然后,系统各部分的主要参与者对照如下:1.创造权限 - Creator创造,2.分配权限 - Administrator 分配,3.使用权限 - User:
1. Creator 创造 Privilege, Creator 在设计和实现系统时会划分,一个子系统或称为模块,应该有哪些权限。这里完成的是 Privilege 与 Resource 的对象声明,并没有真正将 Privilege 与具体Resource 实例联系在一起,形成Operator。
2. Administrator 指定 Privilege 与 Resource Instance 的关联。在这一步, 权限真正与资源实例联系到了一起, 产生了Operator(Privilege Instance)。Administrator利用Operator这个基本元素,来创造他理想中的权限模型。如,创建角色,创建用户组,给用户组分配用户,将用户组与角色关联等等...这些操作都是由 Administrator 来完成的。
3. User 使用 Administrator 分配给的权限去使用各个子系统。Administrator 是用户,在他的心目中有一个比较适合他管理和维护的权限模型。于是,程序员只要回答一个问题,就是什么权限可以访问什么资源,也就是前面说的 Operator。程序员提供 Operator 就意味着给系统穿上了盔甲。Administrator 就可以按照他的意愿来建立他所希望的权限框架可以自行增加,删除,管理Resource和Privilege之间关系。可以自行设定用户User和角色Role的对应关系。(如果将 Creator看作是 Basic 的发明者, Administrator 就是 Basic 的使用者,他可以做一些脚本式的编程) Operator是这个系统中最关键的部分,它是一个纽带,一个系在Programmer,Administrator,User之间的纽带。
9. 样例:
10. 实现:
11.

你参考一下,可能有用。我也正在做。
caoit 2003-08-21
  • 打赏
  • 举报
回复
学习
StudyNet 2003-08-21
  • 打赏
  • 举报
回复
学习。
angel99 2003-08-21
  • 打赏
  • 举报
回复
那从dataset中读出来显示menu 的代码何时如何执行?aspMenu的属性和方法哪里可以查到?
加载更多回复(7)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧