我正在开发一个Rails Web应用程序,它目前被大约20个用户使用。
应用程序的某些部分只能由某些用户访问,因此我们已经有了一个基本的授权框架,我使用acts_as_authenticated插件实现了该框架。
用户的权限取决于他们在哪个部门工作,因此例如管理可以访问应用程序的所有部分,而会计只能访问与会计相关的部分,而销售只能访问与销售相关的部分等等。
另一方面,用户会看到指向他们没有特权的操作的链接。例如,销售部门的人员会在主菜单中看到指向财务记录的链接,但是当他们点击它时,没有任何反应。这是因为AFAIK没有使用acts_as_authenticated查询用户权限的有效方法。
我想以两种方式改变这种情况:
我想介绍更细粒度的授权。目前,授权在控制器级别完成。我想在动作或模型级别执行此操作。例如,我希望销售部门的人能够创建和更新付款,但不能删除它们。
我希望能够有效地查询用户权限,这样我就可以从界面中删除不必要的(并且令人困惑的)链接。
您认为实施此方法的最佳方式是什么?
Rails特定的答案不是必需的,我只是想知道如何在数据驱动的应用程序中实现它。
最后,这是目前的实施方式:
def authorized?
current_user.role.foo? or current_user.role.bar?
end
这是我最初的想法,我认为这不是解决这个问题的最佳方法:
+------------+------------+---------+ | department | controller | action | +------------+------------+---------+ | accounting | payments | index | | accounting | payments | new | | accounting | payments | create | | accounting | payments | edit | | accounting | payments | update | | accounting | payments | destroy | | sales | payments | new | | sales | payments | create | | sales | payments | edit | | sales | payments | update | +------------+------------+---------+
或
+------------+----------+-------+--------+------+--------+--------+ | department | model | list | create | read | update | delete | +------------+----------+-------+--------+------+--------+--------+ | accounting | payments | TRUE | TRUE | TRUE | TRUE | TRUE | | sales | payments | FALSE | TRUE | TRUE | TRUE | FALSE | +------------+----------+-------+--------+------+--------+--------+
答案 0 :(得分:3)
根据我的理解,授权的基本概念是一个角色。 角色可以表达各种各样的事情:
非常精细的授权系统应该允许您根据上述任何标准为用户定义角色。此外,它应该允许您为用户设置多个角色。 (Rails最简单的授权插件形式通常允许您只定义第一种角色,并为用户设置一个角色。)
授权的另一部分是一种机制,如果用户适合某个角色(角色集),则根据事实决定运行(或不运行)代码的哪一部分。要应用此机制,我们必须找到授权应该发生的点,并选择代码应该或不应该运行的角色。
在Rails中对我有用的方法是在模型级别定义角色并保留授权机制(为我想要授权的代码部分设置允许的角色,并询问当前用户是否具有允许的角色完全为控制器/视图运行部分。
为此我使用调整的rails-authorization-plugin,它具有我刚才提到的所有可能性(各种角色,一个用户的许多角色,控制器和视图级别的授权)。
答案 1 :(得分:0)
您可能需要在模型中引入“功能点”或“功能”的概念作为访问控制点; “要素”可能具有可选的“父要素”以形成层次结构。您可以决定什么是功能,哪些不是功能,并以编程方式检查权限。这还应该允许您在绘制菜单之前检查功能级别的访问权限,以便用户永远不会看到指向不允许访问的页面的链接。
描述了类似的情况/解决方案here
答案 2 :(得分:0)
在您的两个提案中,第一个选项看起来更好一点,因为它允许您添加可能不是模型级操作的操作。我猜你会遇到第二个模型做得不够的情况,你需要更改架构或在整个应用程序中开始使用权限逻辑(例如“没有'创建'访问权限的用户也无法运行方法xxx“)
我认为解决方案看起来不太干的原因是重复:
关于#1,创建一个department表并给每个部门一个Id是有意义的。
关于#2,我同意第一条评论。您可以将各种控制器和操作集群到功能组中,然后在用户和功能之间设置多对多关系(映射表)。然后,函数与它们允许的动作/控制器具有一对多的关系。这会让你以最小的重复次数说出“会计和销售应该能够阅读所有财务表格”。