基于身份验证票据的权限系统的实现

 

普遍的身份验证过程由用户表。权限表,用户权限对照表,角色表,角色权限对照表等表组成。表结构一般如下:

 

用户登录时。校验用户表中的用户名与密码是否与输入的一致。一致时表示登录成功。将用户名或ID保存在Session中,当需要判断某个权限的时候,从用户权限表中看有没有存在用户ID与权限表ID的行。有时说明此用户有此权限,否则取出用户所属角色,查看他所属的角色组是否有权限进行此操作。如果没有,再从角色父子关系表中取这个角色的父,一直递归到没有父角色为止。如果最后都没有权限,说明此用户没有权限。

这种传统的身份验证方式,每进行一次身份认证要经过无数此数据库查询操作,即使写成存储过程,效率也相当低下。对于简单的网站或应用还应付得了。对于大型网站来说,这种身份认证方式将使数据库成为网站速度的瓶颈。

在我将要提到的身份认证系统,数据库结构设计如下:


 

在这个结构中用户表的用户权限列为Binary类型。每一位代表一个权限。权限对照表的ID对应此Binary的位置。这样每个字节可以表示8种权限。由于binary可以支持8K位长。因此8K*8种权限,能满足各种需要。为了方便使用,也可以以一个字节表示一种权限。虽然只可以支持8K种权限,但也足够满意各种需求了。

当用户登录时,对照用户表中的用户名和密码,对比成功后将用户权限加密后存储到用户cookie或隐藏域中。用于WinForm程序,也可以存放到类静态变量中。需要验证权限时。从对照表中取出ID,跟用户权限中的位对比。如果都是1,即表明此用户有权限。这样只需要一次数据库交互即可以确定用户有没有此权限。这样数据库压力会得到很大的缓解。

上面的角色表、用户角色表、角色父子关系表只用于授权时使用。给用户授权、取消权限、角色管理时。对这几个表运算后得到的用户权限存放到用户表中即可。

如果在系统启动时将角色表加载到内存中,甚至1次数据库交互都不用就可以判断出权限。当然这种算法也有缺点,比如如果将用户权限保存到用户cookie中的话,如果用户不重新登录,新权限将不起作用。但即使每次都从数据表中取数据。也只有两次数据库交互。这两者就要看实际需求了。

有人可能会质疑二进制操作的效率问题。实际上二进制操作比字符串操作要快的多。可以想像,表示32种权限只需要4个字节的操作。而用平常判断权限的方法。至少要32个整数即32*4=128个字节的操作。

细心的读者可能会发现。我上面没有提到将权限信息放到session中。我提到的这算法,是我在使用.net开发时使用的。.net更新程序时很容易引起应用程序重启。除非Session使用SQL ServerSession Server,当应用程序重启时Session会丢失,用户体验非常差。.net中身份验证票据加密后保存到Cookie中虽然有一定的风险,但我相信随着.net Framework 2.0的推出和微软不断的努力,安全性是还足够的。

稍候我会放出一个.net版实例代码供大家参考。也希望大家提出宝贵意见。

posted on 2005-09-01 00:43  rainlake  阅读(6477)  评论(20编辑  收藏  举报

导航