25

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

设想

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

过去,我选择了以下两种我知道的方法之一。

  1. 使用具有用于确定如何应用参数的特殊列的单个权限表。此示例中的特殊列是TypeIDTypeAuxID。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
    

我的想法

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

第一个示例需要较少的工作,但它们都不是最好的答案。有没有更好的方法来处理这个?

4

5 回答 5

14

我同意约翰唐尼的观点。

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

于 2008-08-04T18:23:40.537 回答
10

我通常对权限系统进行编码的方式是有 6 个表。

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

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

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

于 2008-08-04T17:56:26.643 回答
2

除了 John Downey 和 jdecuyper 的解决方案之外,我还在位域的末尾/开头添加了一个“显式拒绝”位,以便您可以按组、角色成员执行附加权限,然后根据显式拒绝减去权限条目,很像 NTFS 作品,权限方面。

于 2008-08-04T18:39:56.120 回答
2

老实说,ASP.NET 成员资格/角色功能非常适合您描述的场景。编写自己的表/过程/类是一个很好的练习,你可以很好地控制微小的细节,但是在我自己这样做之后,我得出结论最好只使用内置的 .NET 东西。许多现有代码旨在解决它,这很好。从头开始写作花了我大约 2 周的时间,它远没有 .NET 强大。你必须编写这么多废话(密码恢复、自动锁定、加密、角色、权限接口、大量 procs 等),而时间可以更好地花在其他地方。

抱歉,如果我没有回答您的问题,我就像有人问 vb 问题时说要学习 c# 的人。

于 2008-08-07T02:23:18.460 回答
0

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

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

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

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

于 2008-08-04T18:03:57.190 回答