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

问题描述:

我经常遇到以下情况,我需要提供许多不同类型的权限。我主要使用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 [email protected] 
    AND ([email protected] OR [email protected] OR 
(emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1 
ORDER BY q.QID ASC 

我的思想

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

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

我同意约翰唐尼。

个人而言,我有时会使用标记的权限枚举。通过这种方式,您可以对枚举项目使用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)来验证用户是否具有特定权限。

+1

我用这种方法发现的问题是,使用这种方法很容易耗尽角色。正如你所看到的,6个角色的值为2^6 = 64,当31个角色将有2^31 = 2,147,483,647这是最大的int值。所以在T-SQL中,可以使用的最大数据类型是bigint(2^63)。当然你可以使用varchar类型,但是当我有很多角色时,我更喜欢使用John Downey的解决方案。 – 2011-10-07 00:47:08

我通常关于编码权限系统的方式是有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,但这对我来说一直是一种有效的方法,而且我发现它的规模很好。

除了John Downey和jdecuyper的解决方案之外,我还在位域的末尾添加了一个“Explicit Deny”位,以便您可以通过组,角色成员身份执行附加权限,然后减去权限基于明确的拒绝条目,非常像NTFS的工作,权限明智。

老实说,ASP.NET Membership/Roles功能对于你描述的场景来说是完美的。编写你自己的tables/procs/classes是一个很好的练习,你可以很好地控制一些细节,但自己做完这些之后,我总结出最好只使用内置的.NET。很多现有的代码都是为了解决这个问题而设计的,它很好。从头开始写了大约2周的时间,并没有像.NET那样健壮。你必须编写如此多的废话(密码恢复,自动锁定,加密,角色,许可界面,吨过程等),时间可以更好地花在其他地方。

对不起,如果我没有回答你的问题,我就像那个人说谁学习c#时,有人问一个vb问题。