9

我打算在这里问一个问题,关于我对某些用户/角色数据库表的设计是否可以接受,但经过一些研究,我遇到了这个问题:

处理多种权限类型的最佳方法是什么?

这听起来像是一种创新方法,因此我将多个权限定义为单个小数(我假设为 int 数据类型),而不是多对多关系 users_to_roles 表。这意味着单个用户的所有权限都在一行中。在您阅读其他问题和答案之前,它可能没有意义

我无法解决这个问题。有人可以解释一下转换过程吗?这听起来“正确”,但我只是不知道如何在角色进入数据库之前将其转换为小数,以及当它从数据库中出来时如何转换回来。我正在使用 Java,但如果你把它去掉,那也很酷。

这是另一个问题被删除的机会的原始答案:

“就个人而言,我有时会使用标记的权限枚举。这样你就可以对枚举项使用 AND、OR、NOT 和 XOR 位运算。

[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}

然后,您可以使用 AND 位运算符组合多个权限。

例如,如果用户可以查看和编辑用户,则操作的二进制结果是 0000 0011 转换为十进制是 3。然后您可以将一个用户的权限存储到数据库的单个列中(在我们的例子中它会是 3)。

在您的应用程序中,您只需要另一个按位运算 (OR) 来验证用户是否具有特定权限。”

4

2 回答 2

6

您使用按位运算。伪代码将类似于:

bool HasPermission(User user, Permission permission) {
    return (user.Permission & permission) != 0;
}

void SetPermission(User user, Permission permission) {
    user.Permission |= permission;
}

void ClearPermission(User user, Permission permission) {
    user.Permission &= ~permission;
}

权限是您帖子中定义的枚举类型,但无论它是什么类型都需要基于类似整数的类型。这同样适用于 User.Permission 字段。

如果这些运算符(&、|= 和 &=)对您没有意义,那么请阅读按位运算(按位与和按位或)。

于 2008-09-13T00:58:29.343 回答
3

实际上,这就是我们在我担任 DBA 的相当大的 Web 应用程序中确定权限的方式。

如果你打算做这样的事情,你会真正受益于拥有一个 数字表。它将使您的计算速度更快。

基本设置包括下表:

  1. 组 - 用于处理多对多用户和安全点
  2. 安全点 - 包含匿名授权的值和不属于单独组的经过身份验证的用户的值
  3. 组安全点连接表
  4. 一个特殊的 BitMask 数字表,其中包含 ^2 值的条目。因此,2 (2) 有一个条目,3 (2 和 1) 有两个条目。这使我们不必每次都计算值。

首先,我们确定用户是否登录。如果不是,我们返回安全点的匿名授权。

EXISTS接下来,我们通过简单的使用来确定用户是否是与安全点关联的任何组的成员JOIN。如果不是,我们将返回与经过身份验证的用户关联的值。我们系统上的大多数匿名和经过身份验证的默认值都设置为 1,因为我们要求您属于特定组。

注意:如果匿名用户没有访问权限,界面会将他们扔到一个登录框,以允许他们登录并重试。

如果用户一个或多个组的成员,那么我们从 BitMask 表中为为组定义的每个值选择不同的值。例如,如果您属于三个组,并且其中一个授权级别为 8,一个为 12,最后一个为 36,则我们对位掩码表的选择将分别返回 8、8 和 4,以及 4 和 32。通过执行 distinct 我们得到数字 4、8 和 32,它们正确位掩码为 101100。

该值作为用户授权级别返回并由网站处理。

有道理?

于 2008-09-13T00:32:47.860 回答