61

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

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

用户 ID 管理用户 管理产品 管理促销 管理订单
1 真的 真的 真的 真的
2 假 真 真 真
3假假假真假

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

用户 ID 权限(8 位掩码),将是表中的整数
1 00001111
2 00000111
3 00000001

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

谢谢!

4

9 回答 9

83

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

虽然可能更笨重,但拥有一个可能的权限表、一个用户表以及它们之间的链接表是组织它的最佳和最清晰的方式。它还使您的查询和维护(尤其是对于新人)更容易。

于 2008-10-13T22:42:00.667 回答
34

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

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

于 2008-10-13T22:32:02.637 回答
25

我已经做到了两种方式。但我不再使用位掩码了。给定用户 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
于 2008-10-13T22:38:16.353 回答
10

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

我强制应用程序只授权角色(从不用户)。请注意角色表中的“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
)
于 2008-10-13T23:43:35.707 回答
4

如果您在托管环境中,则可以使用 Active Directory 或其他 LDAP 实现。这样,确定权限的安全组可以由一线支持人员使用他们很可能已经熟悉的技术进行管理。

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

于 2009-04-10T23:10:02.413 回答
3

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

基本思想是通过针对框架而不是特定存储机制编写权限检查来利用现有框架。然后,您可以插入任何可用的存储机制,无论是 XML 文件、数据库,甚至是使用 Windows 软件授权管理器的授权存储(例如,它可以让您将自定义权限无缝绑定到 LDAP - 否配置所需的代码)。

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

有关更多信息,请参阅实现角色提供程序。完全有可能其他语言/环境也有可以用来实现这个概念的库——这值得研究。

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

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

于 2008-10-13T22:44:32.720 回答
1

我已经看到了一些类似于您所建议的有限权限系统 - 以及一些真正糟糕的系统。在一些简单的情况下,只要应用程序不变得更复杂,它们是可以接受的。然而,在很多情况下,它们确实变得更加复杂,并且必须重写系统以适应所需的功能。

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

尽管 ACL 建议使用列表实现,但最好使用表格;这个答案是一个好方法。

于 2008-10-13T22:41:05.753 回答
1

无法发表评论,因为我是 SO 新手,但关于公认的答案 - 此解决方案带来的一个巨大优势是能够普遍处理权限,而不仅仅是代码中各处的 if 语句,以及特殊能力例如允许临时权限(有过期日期的权限)

于 2019-07-19T04:37:16.457 回答
0

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

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

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` ) 
于 2008-10-13T22:32:55.957 回答