处理多种权限类型的最佳方法是什么?
我经常遇到以下情况,其中我需要提供许多不同类型的权限。我主要在SQL Server 2000中使用ASP.NET/VB.NET。
设想
我想提供一个可以在不同参数上工作的动态权限系统。假设我想授予部门或者特定人员访问应用程序的权限。并假装我们拥有不断增长的应用程序。
过去,我选择了我知道的以下两种方法之一。
- 将单个许可权表与特殊列一起使用,这些特殊列用于确定如何应用参数。本示例中的特殊列为TypeID和TypeAuxID。 SQL看起来像这样。
SELECT COUNT(PermissionID) FROM application_permissions WHERE (TypeID = 1 AND TypeAuxID = @UserID) OR (TypeID = 2 AND TypeAuxID = @DepartmentID) AND ApplicationID = 1
- 对每种类型的权限使用一个映射表,然后将它们全部结合在一起。
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
我的想法
我希望这些例子有意义。我把它们拼凑在一起。
第一个示例需要较少的工作,但是它们都不是最佳答案。有没有更好的方法来解决这个问题?
解决方案
回答
我通常使用的编码权限系统的方法是有6个表。
- 用户-这很简单,这是典型用户表
- 组-这将是我们部门的同义词
- 角色-这是一个具有所有权限的表,通常还包括易于理解的名称和说明
- Users_have_Groups-这是用户所属的组的多对多表
- Users_have_Roles-另一个表,其中列出了将哪些角色分配给单个用户
- Groups_have_Roles-每个组具有哪些角色的最终多对多表
在用户会话开始时,我们将运行一些逻辑,以提取他们已分配的每个角色(目录或者组)。然后,我们针对这些角色进行编码,作为安全权限。
就像我说的那样,这是我通常要做的,但是年龄可能会有所不同。
回答
我在各种应用程序中使用的一种方法是拥有一个通用的PermissionToken类,该类具有可更改的Value属性。然后,我们查询所请求的应用程序,它告诉我们使用它需要哪些PermissionTokens。
例如,"运送"应用程序可能会告诉我们它需要:
new PermissionToken() { Target = PermissionTokenTarget.Application, Action = PermissionTokenAction.View, Value = "ShippingApp" };
显然,这可以扩展到创建,编辑,删除等,并且由于自定义Value属性,任何应用程序,模块或者小部件都可以定义其自己所需的权限。 YMMV,但这对我来说一直是一种有效的方法,我发现它可以很好地扩展。
回答
我同意约翰·唐尼的观点。
就个人而言,有时会使用标记的权限枚举。这样,我们可以对枚举项使用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)即可验证用户是否具有特定的权限。
回答
除了John Downey和jdecuyper的解决方案之外,我还在位域的末尾/开头添加了" Explicit Deny"位,以便我们可以按组,角色成员身份执行加性权限,然后根据显式拒绝减去权限条目,就像NTFS一样,都是基于权限的。
回答
老实说,ASP.NET成员资格/角色功能可以完美地适用于我们描述的方案。编写自己的表/ procs /类是一个很好的练习,我们可以很好地控制分钟的细节,但是我自己做完此后,我得出结论,最好只使用内置的.NET内容。很多现有的代码都是为了解决这个问题而设计的,这很好。从头开始写花了我大约2周的时间,它远没有.NET强大。我们必须编写大量的废话(密码恢复,自动锁定,加密,角色,权限界面,大量的proc等),这样的时间可能会花在其他地方更好。
抱歉,如果我没有回答问题,我就像那个在有人问VB问题时说要学习的人。