应用逻辑与授权

时间:2014-08-29 18:36:13

标签: ruby-on-rails authorization cancan

我在Rails中使用cancan gem,但这可能比这更通用。

简短介绍。在cancan中,您可以像这样定义授权:

can :read, Post
can :manage, Post if user.is_admin?
can :manage, Post do |post| post.author == user end

这意味着任何人都可以阅读Post,但只有作者和管理员可以管理(编辑/销毁)它们。

现在我想更改我的应用程序逻辑,这样如果它有任何注释你就不能删除你的帖子(除非你是管理员)。使用cancan(在上一个代码段末尾添加)仍然很容易:

cannot :destroy, Post do |post| post.comments.count > 0 && !user.is_admin? end

这意味着我可以在视图中使用以下伪代码(HTML模板):

<h1><%=post.title%></h1>
<p><%=post.text%></p>
<%=link_to 'Edit', edit_post_path(post) if can? :edit, post%>
<%=link_to 'Delete', delete_post_path(post) if can? :destroy, post%>

我唯一的问题是将权限本身与应用逻辑混合是否合理?感觉有点脏,但另一方面,我需要打破DRY并在应用程序的任何地方(前端,API等)进行双重检查来替换它

<h1><%=post.title%></h1>
<p><%=post.text%></p>
<%=link_to 'Edit', edit_post_path(post) if post.can_be_edited? && can? :edit, post%>
<%=link_to 'Delete', delete_post_path(post) if post.can_be_destroyed? && can? :destroy, post %>

2 个答案:

答案 0 :(得分:1)

我没有发现在您建议的位置检查授权相关行为的任何问题。如你所述,替代方案更糟糕。此外,这意味着有人可以轻松地在一个位置查看Post的授权方案,这是非常需要的。替代方案(在多个地方进行检查)更难以维护和推理,更不用说改变必须在多个地方进行编辑,而且它只是一个绅士协议和&#39; #39;开发人员同时编辑它们以使它们保持同步。

答案 1 :(得分:0)

除了tmruss的评论之外,我还想补充一点,您尝试对cancan执行的操作称为外部授权。这是一个很好的方法。您应该始终努力将授权逻辑与业务逻辑分离。

最重要的是你在相关的地方做检查。如果你不知道这些相关的地方是什么,那么你需要回到应用程序的绘图板来确定所有入口点。这些入口点是您要应用细粒度授权/ cancan的位置。

请查看XACML reference architecture以获取正式的架构概述。