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

时间:2008-08-04 17:46:28

标签: sql permissions

我经常遇到以下场景,我需要提供许多不同类型的权限。我主要使用ASP.NET / VB.NET和SQL Server 2000。

方案

我想提供一个可以处理不同参数的动态权限系统。假设我想要一个部门或只是一个特定的人访问一个应用程序。并假装我们有许多应用程序不断增长。

过去,我选择了以下两种方法中的一种来做到这一点。

  1. 使用具有用于的特殊列的单个权限表 确定如何应用参数。中的专栏 此示例是TypeID和TypeAuxID。 SQL会看起来像什么 像这样。

    SELECT COUNT(PermissionID)
    FROM application_permissions
    WHERE
    (TypeID = 1 AND TypeAuxID = @UserID) OR
    (TypeID = 2 AND TypeAuxID = @DepartmentID)
    AND ApplicationID = 1
    
  2. 为每种类型的权限使用映射表,然后加入它们 一起来。

    SELECT COUNT(perm.PermissionID)
    FROM application_permissions perm
    LEFT JOIN application_UserPermissions emp
    ON perm.ApplicationID = emp.ApplicationID
    LEFT JOIN application_DepartmentPermissions dept
    ON perm.ApplicationID = dept.ApplicationID
    WHERE q.SectionID=@SectionID
      AND (emp.UserID=@UserID OR dept.DeptID=@DeptID OR
     (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
    ORDER BY q.QID ASC
    
  3. 我的想法

    我希望这些例子有意义。我把它们拼凑在一起。

    第一个例子需要较少的工作,但他们都不是最好的答案。有没有更好的方法来解决这个问题?

5 个答案:

答案 0 :(得分:12)

我同意约翰唐尼的意见。

就个人而言,我有时会使用标记的权限枚举。这样,您可以对枚举的项使用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 然后,您可以将一个用户的权限存储到DataBase的单个列中(在我们的示例中为3)。

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

答案 1 :(得分:9)

我通常使用编码权限系统的方式是有6个表。

  • 用户 - 这非常简单,它是典型的用户表
  • 群组 - 这将是您所在部门的同义词
  • 角色 - 这是一个包含所有权限的表,通常还包括人类可读的名称和描述
  • Users_have_Groups - 这是一个包含用户所属组的多对多表格
  • Users_have_Roles - 分配给单个用户的另一个多对多表格
  • Groups_have_Roles - 每个组具有哪些角色的最终多对多表

在用户会话开始时,您将运行一些逻辑来提取他们分配的每个角色,无论是目录还是通过组。然后,您将这些角色编码为安全权限。

就像我说的那样,这是我通常会做的,但你的琐事可能会有所不同。

答案 2 :(得分:2)

老实说,ASP.NET Membership / Roles功能可以完美地适用于您描述的场景。编写自己的表/ procs / classes是一个很好的练习,你可以非常好地控制细节,但是在我自己完成之后我已经得出结论,最好只使用内置的.NET东西。很多现有的代码都是为解决它而设计的,这很好。从头开始写作花了我大约2周的时间,并没有像.NET那样强大。你必须编写如此多的垃圾代码(密码恢复,自动锁定,加密,角色,权限界面,大量的触发器等),并且时间可以更好地花在其他地方。

很抱歉,如果我没有回答你的问题,我就像有人在问某个问题时说要学习c#。

答案 3 :(得分:2)

除了John Downey和jdecuyper的解决方案之外,我还在位域的末尾开始添加了“显式拒绝”位,以便您可以按组,角色成员身份执行附加权限,然后基于权限减去在显式拒绝条目时,非常像NTFS工作,许可方式。

答案 4 :(得分:0)

我在各种应用程序中使用的方法是拥有一个具有可更改Value属性的通用PermissionToken类。然后查询请求的应用程序,它会告诉您使用它需要哪些PermissionTokens。

例如,Shipping应用程序可能会告诉您需要:

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

这显然可以扩展到Create,Edit,Delete等,并且由于自定义Value属性,任何应用程序,模块或窗口小部件都可以定义自己所需的权限。 YMMV,但这对我来说一直是一种有效的方法,我发现它可以很好地扩展。