5

我正在开发一个 Rails Web 应用程序,目前有大约 20 个用户正在使用它。

应用程序的某些部分只能由某些用户访问,因此我们已经有了一个基本的授权框架,我使用acts_as_authenticated 插件实现了它。

用户的权限取决于他们在哪个部门工作,例如管理可以访问应用程序的所有部分,而会计只能访问与会计相关的部分,而销售只能访问与销售相关的部分等。

另一方面,用户会看到指向他们没有足够权限的操作的链接。例如,销售部门的人员在主菜单中看到一个指向财务记录的链接,但当他们单击它时,什么也没有发生。之所以如此,是因为 AFAIK 没有使用acts_as_authenticated 查询用户权限的有效方法。

我想通过两种方式改变它:

  1. 我想引入更细粒度的授权。目前,授权是在控制器级别完成的。我想在动作或模型级别执行此操作。例如,我希望销售部门的人员能够创建和更新付款,但不能删除它们。

  2. 我希望能够有效地查询用户权限,这样我就可以从界面中删除不必要的(和令人困惑的)链接。

你认为最优雅的实现方式是什么?

不需要特定于 Rails 的答案,我只想知道如何在数据驱动的应用程序中实现这一点。

最后,这是它目前的实现方式:

def authorized?
  current_user.role.foo? or current_user.role.bar?
end

这是我最初的想法,我认为这不是解决这个问题的最佳方法:

+------------+------------+---------+
| 部门 | 控制器 | 行动 |
+------------+------------+---------+
| 会计| 付款 | 索引 |
| 会计| 付款 | 新 |
| 会计| 付款 | 创建 |
| 会计| 付款 | 编辑 |
| 会计| 付款 | 更新 |
| 会计| 付款 | 销毁|
| 销售 | 付款 | 新 |
| 销售 | 付款 | 创建 |
| 销售 | 付款 | 编辑 |
| 销售 | 付款 | 更新 |
+------------+------------+---------+

或者

+------------+----------+--------+--------+------+- --------+--------+
| 部门 | 型号 | 列表 | 创建 | 阅读 | 更新 | 删除 |
+------------+----------+--------+--------+------+- --------+--------+
| 会计| 付款 | 真的 | 真的 | 真的 | 真的 | 真的 |
| 销售 | 付款 | 错误 | 真的 | 真的 | 真的 | 错误 |
+------------+----------+--------+--------+------+- --------+--------+
4

3 回答 3

3

据我了解,授权的基本概念是一个角色。角色可以表达各种东西:

  1. 用户与整个系统的关系(例如,成为系统的管理员)
  2. 用户与某种实体的关系(例如,成为评论的主持人)
  3. 用户与某个特定实体的关系(例如,成为某个资源的所有者)
  4. 其他一些复杂的关系(例如,成为某个资源所有者的用户的朋友)
  5. 该用户具有某些属性或以某种特定方式响应某些消息(例如,成为青少年)

一个真正细粒度的授权系统应该允许您根据上述任何标准为用户定义角色。此外,它应该允许您为用户设置多个角色。(Rails 最简单的授权插件形式通常只允许您定义第一种角色并为用户设置一个角色。)

授权的另一部分是一种机制,它根据用户是否适合某个角色(角色集)这一事实来决定运行(或不运行)代码的哪一部分。要应用这种机制,我们必须找到应该进行授权的点,并选择应该或不应该运行代码的角色。

在 Rails 中对我有用的方法是在模型级别定义角色并保留授权机制(为我想要授权的代码部分设置允许的角色,并询问当前用户是否具有允许运行该部分的角色) 完全用于控制器/视图。

为此,我使用了经过调整的 rails-authorization-plugin,它具有我刚才提到的所有可能性(各种角色、一个用户的多个角色、控制器和视图级别的授权)。

于 2008-11-11T14:57:58.583 回答
0

您可能需要在模型中引入“功能点”或“特征”的概念作为访问控制点;一个“特征”可能有一个可选的“父特征”来形成一个层次结构。您可以决定什么是功能,什么不是功能,并以编程方式检查权限。这还应该允许您在绘制菜单之前检查功能级别的访问权限,以便用户永远不会看到指向他们不允许访问的页面的链接。

此处描述了类似的情况/解决方案

于 2008-11-11T02:53:12.290 回答
0

在您的两个提案中,第一个选项看起来更好一些,因为它允许您添加可能不是模型级操作的操作。我猜您会遇到第二种模型做得不够的情况,您需要更改架构或开始在整个应用程序中添加权限逻辑(例如“没有“创建”访问权限的用户也无法运行方法 xxx")

我认为解决方案看起来不太干燥的原因是存在重复:

  1. 在部门名称中,以及
  2. 在部门能力

关于#1,创建一个部门表并给每个部门一个 ID 是有意义的。

关于#2,我同意第一条评论。您可能可以将各种控制器和操作聚集到功能组中,然后在用户和功能之间设置多对多关系(映射表)。然后,函数将与它们允许的操作/控制器具有一对多的关系。这将让您以最少的重复,说出诸如“会计和销售应该能够阅读所有财务表格”之类的内容。

于 2008-11-11T07:46:58.860 回答