您可能有兴趣阅读Steffen Bartsch 的这篇文章。它总结了 Ruby on Rails 的所有授权插件,我相信它会帮助您找到解决方案(虽然本文是关于 Rails 插件的,但这些概念很容易在 Rails 之外导出)。
Steffen 还构建了自己的插件,称为“声明式授权”,它似乎符合您的需求,恕我直言:
- 一方面,您定义角色(例如“访客”、“管理员”……)。您的用户与这些角色相关联(以多对多关系)。您将这些角色映射到权限(同样是多对多关系)。每个特权都链接到给定的上下文。例如,角色“访问者”可能具有“阅读文档”的权限。在本例中,“ read ”是权限,它应用于“ documents ”上下文。
- 注意:在 Steffen 的插件中,您可以定义角色的层次结构。例如,您可能希望“ global_admin ”角色包括“ document_admin ”角色,以及“ comment_admin ”角色等。
- 您还可以定义权限层次结构:例如,“管理”权限可以包括“读取”、“更新”、“添加”和“删除”权限。
- 另一方面,您根据权限和上下文而不是角色来编写应用程序的思维方式。例如,显示文档的动作应该只检查用户是否具有在“文档”上下文中“阅读”的权限(无需检查用户是否具有“访问者”角色或任何其他角色)。这极大地简化了您的代码,因为大多数授权逻辑都在其他地方提取(甚至可能由其他人定义)。
用户角色的定义和应用程序级权限的定义之间的这种分离保证了您的代码不会在每次定义新角色时发生变化。例如,以下是控制器中访问控制的简单程度:
class DocumentController [...]
filter_access_to :display, :require => :read
def display
...
end
end
在视图内部:
<html> [...]
<% permitted_to?(:create, :documents) do %>
<%= link_to 'New', new_document_path %>
<% end %>
</html>
Steffen 的插件还允许对象级(即行级)访问控制。例如,您可能想要定义一个角色,如“ document_author ”,并赋予它“documents”的“ manage ”权限,但前提是用户是文档的作者。该规则的声明可能如下所示:
role :document_author do
has_permission.on :documents do
to :manage
if_attribute :author => is {user}
end
end
这里的所有都是它的!您现在可以像这样获取允许用户更新的所有文档:
Document.with_permissions_to(:update)
由于“管理”权限包括“更新”权限,这将返回作者为当前用户的文档列表。
当然,并非每个应用程序都需要这种级别的灵活性……但您可能需要。