管理Web应用程序权限的最佳方法是什么 - 位掩码或数据库表?

时间:2008-10-13 22:27:10

标签: database-design web-applications permissions

我正在考虑为“管理员”Web应用程序设计权限系统的最佳方法。该应用程序可能有许多用户,每个用户都可以被分配一定的角色;可以允许其中一些用户执行角色之外的特定任务。

我可以想到两种设计方法:一种是“权限”表,每个用户都有一行,布尔列,每个任务一个,为他们分配执行这些任务的权限。像这样:

User ID          Manage Users     Manage Products     Manage Promotions     Manage Orders
1                true             true                true                  true
2                false            true                true                  true
3                false            false               false                 true

我想到的另一种方法是使用位掩码来存储这些用户权限。对于32位有符号整数,这会将可管理的任务数限制为31,但实际上我们不可能有超过31个用户可以执行的特定任务。这样,数据库模式就会更简单,每次添加需要访问控制的新任务时,我们都不必更改表结构。像这样:

User ID          Permissions (8-bit mask), would be ints in table
1                00001111
2                00000111
3                00000001

这里通常使用什么机制,为什么?

谢谢!

9 个答案:

答案 0 :(得分:72)

我认为远离编码宇宙意义的神秘位串是一般的经验法则。

虽然可能更笨拙,但拥有可能的权限表,用户表以及它们之间的链接表是组织此操作的最佳和最清晰的方法。它还使您的查询和维护(特别是对于新人)更容易。

答案 1 :(得分:31)

如何创建Permission表,然后是UserPermission表来存储关系?

您永远不必再次修改结构,并且您可以根据需要添加任意数量的权限。

答案 2 :(得分:22)

我已经两种方式完成了。但我不再使用比特面具了。在用户ID或组ID作为外键的情况下,可以将单独的表用作交叉引用。

UserID | Permission
===================
1      | 1              1 representing manage users
1      | 2              2 being manger products
2      | 3 

这种方式更容易维护并在以后添加。

我还会使用单独的表来管理权限。

PermissionID | Description
==========================
1            | Manage Users
2            | Manager Products

答案 3 :(得分:7)

通常我有一个Users表,一个Roles表和一个UserRoles表。这样,您可以拥有无​​限量的角色,而无需更改数据库结构,用户可以担任多个角色。

我强制应用程序仅授权角色(从不用户)。请注意角色表中的“id”列不是标识列。这是因为您可能需要控制放入此表的ID,因为您的应用程序必须查找特定的ID。

结构如下:

create table Users (
 id int identity not null,
 loginId varchar(30) not null,
 firstName varchar(50) not null,
 etc...
)

create table Roles (
 id int not null,
 name varchar(50) not null
)

create table UserRoles (
 userId int not null,
 roleId int not null
)

答案 4 :(得分:3)

我建议使用角色提供程序的概念来抽象Web应用程序权限。从版本2.0开始,这是在.NET中为System.Web.Security.RoleProvider提供的。

基本思想是通过对框架而不是特定的存储机制编写权限检查来利用现有框架。然后,您可以插入任何可用的存储机制,无论是XML文件,数据库,还是authorization store使用Windows软件授权管理器(它允许您将自定义权限无缝地绑定到LDAP,作为一个示例 - 无需配置代码)。

如果您决定使用数据库作为存储机制,则支持多个数据库来自动创建框架所需的基础表。这包括在Mono上运行.NET并在MySQL之上使用角色提供程序模型。

有关详细信息,请参阅Implementing a Role Provider。完全有可能其他语言/环境也有可以用来实现这个概念的库 - 值得研究。

编辑:我还应该指出Web应用程序与存储机制的关系是如何通过web.config文件完成的,并且不需要更改代码。我发现这对于在我的本地机器上测试代码库的生产版本非常有用,使用XML文件模仿权限而不是普通的数据库提供程序 - 所有这些都通过修改web.config中的两行来完成。

我忘了提到的另一件事是,您可以通过扩展基类来插入自己的自定义提供程序,允许您利用权限模型但仍使用专有存储系统(例如,如果您真的使用位掩码)想要)。

答案 5 :(得分:2)

如果您处于托管环境中,则可以使用Active Directory或其他LDAP实施。这样,确定权限的安全组可以使用他们最熟悉的技术通过一线支持进行管理。

如果您的应用程序是收缩包装,则为Levi Rosol建议对数据库进行规范化,以便您可以在应用程序中拥有可扩展的数据模型。

答案 6 :(得分:1)

我见过许多类似于你所建议的权限系统 - 以及一些真正糟糕的系统。在一些简单的情况下,只要应用程序不复杂,它们就可以接受。但是,在很多情况下,它们确实变得更加复杂,必须重新编写系统以适应所需的功能。

如果您认为有一天可能需要表达能力,我会选择一个包含用户和组(或角色)的完整ACL(访问控制列表)系统。也就是说,由权限管理的每个事物(例如“管理用户”,“管理产品”)都具有ACL,该ACL是可以访问它的所有用户和组的列表。然后,用户可以直接添加到相关的ACL中,也可以添加到已经是ACL成员的组中。

虽然ACL建议列表实现,但你最好使用表格; this answer是个好方法。

答案 7 :(得分:0)

权限通常是关键字,带有1,0或null(表示继承)。使用位系统,您可能无法在用户标识和权限关键字上创建索引;相反,您必须扫描每条记录才能获得权限值。

我会说第一个选择。在我看来,更好的解决方案:

create table permissions (
    user_id INT NOT Null,
    permission VARCHAR(255) NOT NULL,
    value TINYINT(1) NULL
)
alter table `permissions` ADD PRIMARY KEY ( `user_id` , `permission` ) 

答案 8 :(得分:0)

不能发表评论,因为我是SO的新手,但对于公认的答案-此解决方案带来的巨大优势是能够通用处理权限,而不是仅仅检查代码中是否存在语句。作为特殊功能,例如允许临时权限(具有到期日期的权限)