|
主题: 浅谈ASP.NET的权限管理和用户验证
|
 蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#12004/12/17 2:55:00
网站建设中,会碰到最常用的用户管理及操作权限设置验证,虽然这是很常见的一个管理操作,但要做得完善很不容易。最近参考了许多.NET方面的书,特别关心这方面的,并结合自己特点,摸索了一下适合自己的用户管理方法,完成了基本管理类库。
用户的管理方法,在设计时采取“用户——角色——许可”三级,这是WINDOWS操作系统的用户管理方法。一个用户可以有多个角色,一个角色也可以有多个许可。
所以有数据库设计时分别设计:
用户表:设UserID、用户名、用户信息 角色表:设RoleID、CategoryID、RoleName、Description 用户角色表:UserID、RoleID
分类表:CategoryID、CategoryName、Description 许可表:PermissionID、CategoryID、PermissionName、Description 角色许可表:RoleID、PermissionID
设计好数据库后,即可以从事设计用户、角色、许可的类。类库分数据层类,完成建立、查询、删除、更新等操作。业务层的类,需要实现与数据无关功能,建立如用户拥有角色、许可的列表,验证方式等。
在业务层有一很重要的方法,即是用.NET的验证方式来实现,因此建立二个类:
一是 SiteIdentity 类,它继承自业务层基类,并采用System.Security.Principal.IIdentity接口。该类主要存放用户的基本信息,包括用户名、EMAIL及ID号、密码。它的方法较简单,通过验证后,把用户的基本信息。
二是 HelloseaPrincipal 类,它也继承业务基类,采用System.Security.Principal.IPrincipal接口。该类的主要方法有验证类,并把验证后的用户信息、用户角色列表、许可列表存储到类中。该类中有二个方法和一个Property是IIdentity接口必须的,即IsInRole、HasPermission,和System.Security.Principal.IIdentity Identity。
设计完成类库后,即可以用来验证用户了。比如在管理登录页面中,需要判断用户的密码是否正确,并判断用户是否有许可进入管理页面。
下面是验证中的一段: HelloseaPrincipal admin = HelloseaPrincipal.ValidateLogin(txtAdminName.Text, txtPassword.Text); if (admin == null) { labInfo.Text = "没有该管理员帐号,或输入密码不正确。"; } else if ( !admin.HasPermission(1) ) { labInfo.Text = "您并不是管理角色并且没有管理许可,不能进入本系统。"; } else { Context.User = admin; FormsAuthentication.SetAuthCookie(txtAdminName.Text, true); Response.Redirect("AdminIndex.aspx"); }
注:!admin.HasPermission(1)的1是数据库中许可的ID号
在内部页面中可以用: HelloseaPrincipal currentPrincipal = (HelloseaPrincipal)Context.User; if (!currentPrincipal.HasPermission(1)) { } 这样方法来验证用户,虽然它也是通过Cookie,但.net中的Cookie是加密的,能实现很高的安全性。
这样的设计还有个缺点,即是许可的ID号是固定值。考虑到一般的管理页面需要的许可比较固定,所以采用把许可设置在config文件中。而一些频道等需要经常变化的验证许可放置在数据库的频道表中。下面是我采用的config文件中设置方法实现,不详细介绍如何读取和写入了。从config文件读取和写入可采用XML串行化和反串行化很容易实现,可以用类来封装,并且在使用时非常方便,下面的语句即是通过封装类中读取许可的方法: if ( !admin.HasPermission(OperatePermissionConfig.GetSettings().ManagerLogin) ) { }
关于权限和验证,就介绍到这里,只能简单介绍了。因实现的代码非常长,所以这里只是介绍一种思维方式,具体实现每个人都会有自己特点。
编辑历史:[此帖最近一次被 蓝鲸 编辑过(编辑时间:2004-12-17 09:03:52)]
非常大鱼
|
 =ridincal=
职务:管理员
等级:7
金币:20.0
发贴:5886
|
#22004/12/17 10:02:18
不错,非常科学的权限分级管理策略……蓝鲸的Dev风格跟我挺像阿  嗯~分类表有何功用?对权限分类?
|
 janlay
职务:管理员
等级:7
金币:28.0
发贴:7244
|
#32004/12/17 10:19:59
嗯,赞一个,规范化的关系数据库设计  我对分类表的功能也有些疑惑,从列说明上来看,似乎是角色表和许可表的外键,这样意义就不太明确了。烦请蓝鲸出来解释一下吧
|
 蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#42004/12/17 10:23:09
分类表主要对许可和角色分类。因许可和角色分类一般都相同,所以共用同一分类。 比如许可可分系统管理类、文章管理类、论坛管理类,这样在论坛里只要列出论坛管理类的角色或许可就可以了,不需要列出其它的。
非常大鱼
|
 janlay
职务:管理员
等级:7
金币:28.0
发贴:7244
|
#52004/12/17 10:39:31
我觉得这样不太好,如果以后许可和角色的分类要分开,就麻烦了。我宁愿一开始就把两种分类分开。
我以前在做一个 IDC 系统时,相对于你这个来说,增加了一个继承权限功能。我的权限本身就是树状结构的,一个权限可以包含几个权限,每个权限仍然可以包含其他权限。我用这种方式实现了你的Category功能。权限项在默认情况下具有继承上层权限的属性,这样,当权限和角色都很多的时候,可以有效地减少权限定义。
|
 =ridincal=
职务:管理员
等级:7
金币:20.0
发贴:5886
|
#62004/12/17 10:45:53
跟我的猜想一致,分类是对权限(蓝鲸称为“许可”,个人认为这不完全合适,完善的权限应当包含“许可”和“禁止”,就像Windows的本地安全策略,是对默认权限的一种有效补充,安全性更好)的一种摘要,例如:
文章管理类:
论坛用户管理(禁止) |- 增加用户(禁止) |- 删除用户(禁止) |- 编辑用户(禁止) 论坛文章管理(许可) |- 编辑文章(许可) |- 删除文章(许可) 论坛公告管理(部分许可) |- 增加公告(许可) |- 编辑公告(许可) |- 删除公告(禁止)
……………………
|
 janlay
职务:管理员
等级:7
金币:28.0
发贴:7244
|
#72004/12/17 10:51:45
Windows 帐户权限管理本身就是学习的典范,它的“禁止”权限优先级比“许可”高。
我想在有效权限的计算上也是有很多学问的,或许可以引入按位运算来计算最终的有效权限。
|
 蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#82004/12/17 14:35:13
非常大鱼
|
 =ridincal=
职务:管理员
等级:7
金币:20.0
发贴:5886
|
#92004/12/17 15:10:24
“部分许可”是对包含详细权限列表的权限摘要的一种权限描述,实际上没有具体作用
|
 蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#102004/12/17 16:36:19
再补充一点,以上设计的许可是这样的,一个角色拥有的许可就好比拥有的财富一样,如果没有拥有许可,则说明不能做该事。所以只承认有,好比去某个地方,需要这张通行证,这张通行证就是一个许可,所以在设计时也没必要考虑通行证是“禁止”了,因通行证目的只有一个,通行。每一个操作就好比站岗门哨,需要各种通行门票,如果没有,就不能进入这个门了。 回过头来,仔细想着,是否在数据库设计上也与二位有些差别。很想搞清这个,但自己经验和水平也无法推测更好方法,只是想更多了解一点,以后碰到了才会知道这些设计的缺点和优越性。
编辑历史:[此帖最近一次被 蓝鲸 编辑过(编辑时间:2004-12-17 16:45:04)]
非常大鱼
|
 =ridincal=
职务:管理员
等级:7
金币:20.0
发贴:5886
|
#112004/12/17 17:08:40
单一许可方式的授权并非行不通,但是在支持继承性权限和默认权限(举个例子某一角色具有对某一父版块的管理权限,那么默认的,该角色拥有所有该板块中所有子板块的管理权限)的大型系统中将变得不够安全和方便。
|
 蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#122004/12/17 21:40:40
ridincal在上个帖子中说 引用: 单一许可方式的授权并非行不通,但是在支持继承性权限和默认权限(举个例子某一角色具有对某一父版块的管理权限,那么默认的,该角色拥有所有该板块中所有子板块的管理权限)的大型系统中将变得不够安全和方便。
权限设计确实方法很多,也不容易,对继承性我会好好考虑一下。目前我想实现一稍简单一点,但容易扩展的数据库,等以后有一定认识后再考虑复杂的。Category表可有可无,只是为列表时有个分类显示。现在我还是不考虑继承性,因目前权限还比较简单,我怕上去后下不来。其实数据库还是可扩展的,只不过把许可全部看成只有一级的分类树。又找了许多资料,权限设计真是五花八门,并加了许多属性。 权限真很值研究,有非常多学问,二位给我的已很多了。只是现在我做的比较简单,但不容易犯错,虽然实现起来还有很多不方便的地方。 另在网上,有些设计的许可有读、写、编辑、删除等属性,方法真很多,各位有好的想法,真很欢迎。
非常大鱼
|
 shilinow
职务:普通成员
等级:1
金币:0.0
发贴:60
|
#132004/12/24 16:30:25
很好的讨论,听了感觉多了很多思路
|
 偏偏喜欢你
职务:普通成员
等级:1
金币:0.0
发贴:5
|
#142004/12/25 19:43:23
问一下下,在ASP中可不可以用呢 讨论真是精彩
|
 蓝鲸
职务:版主
等级:5
金币:42.1
发贴:2614
|
#152004/12/25 22:17:26
许可与角色的设计是与语言无关的,任何语言均可以用。下文中的窗体验证方法只限ASP.NET,ASP没有这种验证方法,但可以用Cookie或Session进行代替使用。
非常大鱼
|