为Web应用程序实现细粒度授权的最佳方法?

Can*_*der 5 authorization web-applications ruby-on-rails

我正在开发一个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
Run Code Online (Sandbox Code Playgroud)

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

+------------+------------+---------+
| 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  |
+------------+----------+-------+--------+------+--------+--------+

Mil*_*ota 3

据我了解,授权的基本概念是角色。角色可以表达多种事物:

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

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

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

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

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