我经常遇到以下场景,我需要提供许多不同类型的权限。我主要使用ASP.NET / VB.NET和SQL Server 2000。
方案
我想提供一个可以处理不同参数的动态权限系统。假设我想要一个部门或只是一个特定的人访问一个应用程序。并假装我们有许多应用程序不断增长。
过去,我选择了以下两种方法中的一种来做到这一点。
使用具有用于的特殊列的单个权限表 确定如何应用参数。中的专栏 此示例是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
我的想法
我希望这些例子有意义。我把它们拼凑在一起。
第一个例子需要较少的工作,但他们都不是最好的答案。有没有更好的方法来解决这个问题?
答案 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个表。
在用户会话开始时,您将运行一些逻辑来提取他们分配的每个角色,无论是目录还是通过组。然后,您将这些角色编码为安全权限。
就像我说的那样,这是我通常会做的,但你的琐事可能会有所不同。
答案 2 :(得分:2)
除了John Downey和jdecuyper的解决方案之外,我还在位域的末尾开始添加了“显式拒绝”位,以便您可以按组,角色成员身份执行附加权限,然后基于权限减去在显式拒绝条目时,非常像NTFS工作,许可方式。
答案 3 :(得分:2)
老实说,ASP.NET Membership / Roles功能可以完美地适用于您描述的场景。编写自己的表/ procs / classes是一个很好的练习,你可以非常好地控制细节,但是在我自己完成之后我已经得出结论,最好只使用内置的.NET东西。很多现有的代码都是为解决它而设计的,这很好。从头开始写作花了我大约2周的时间,并没有像.NET那样强大。你必须编写如此多的垃圾代码(密码恢复,自动锁定,加密,角色,权限界面,大量的触发器等),并且时间可以更好地花在其他地方。
很抱歉,如果我没有回答你的问题,我就像有人在问某个问题时说要学习c#。
答案 4 :(得分:0)
我在各种应用程序中使用的方法是拥有一个具有可更改Value属性的通用PermissionToken类。然后查询请求的应用程序,它会告诉您使用它需要哪些PermissionTokens。
例如,Shipping应用程序可能会告诉您需要:
new PermissionToken()
{
Target = PermissionTokenTarget.Application,
Action = PermissionTokenAction.View,
Value = "ShippingApp"
};
这显然可以扩展到Create,Edit,Delete等,并且由于自定义Value属性,任何应用程序,模块或窗口小部件都可以定义自己所需的权限。 YMMV,但这对我来说一直是一种有效的方法,我发现它可以很好地扩展。