Security 资源列表授权的最佳实践是什么?

Security 资源列表授权的最佳实践是什么?,security,authorization,Security,Authorization,发布和/或协作应用程序通常涉及共享对资源的访问。在门户中,用户可以作为组成员或由于显式访问而被授予对某些内容的访问权限。完整的内容集可以包括公共内容、组成员资格内容和私人用户内容。或者,对于协作应用程序,我们可能希望将资源作为工作流的一部分进行传递,或者共享文档的保管权以进行编辑 由于大多数应用程序将这些资源存储在数据库中,因此通常会创建诸如“获取我可以编辑的所有文档”或“获取我可以看到的所有内容”之类的查询。其中“可编辑”和“可查看”是用户的权限 我有两个问题: 一旦检索到资源,就可以很容易地

发布和/或协作应用程序通常涉及共享对资源的访问。在门户中,用户可以作为组成员或由于显式访问而被授予对某些内容的访问权限。完整的内容集可以包括公共内容、组成员资格内容和私人用户内容。或者,对于协作应用程序,我们可能希望将资源作为工作流的一部分进行传递,或者共享文档的保管权以进行编辑

由于大多数应用程序将这些资源存储在数据库中,因此通常会创建诸如“获取我可以编辑的所有文档”或“获取我可以看到的所有内容”之类的查询。其中“可编辑”和“可查看”是用户的权限

我有两个问题:

  • 一旦检索到资源,就可以很容易地对用户进行授权,但是如何有效地对可用资源列表执行授权呢?以及

  • 这种授权可以从应用程序的核心中分离出来吗?也许换成单独的服务?一旦分离,您如何过滤查询,如“获取所有我能看到的标题为[SomeSearchTerm]的文档”?在我看来,您的独立系统必须复制大量参考数据


  • 我通常有这样一个模式

    使用者−−∈ 用户文档∋−− 文件

    然后我创建一个视图“ProfiledDocuments”

    选择
    来自文件d
    ud.DocumentId=d.Id上的内部联接用户文档ud
    在u.Id=ud.UserId上加入内部用户u
    
    然后始终使用用户ID筛选器在ProfiledDocuments上运行搜索查询。有了适当的索引,它就足够好了


    如果您需要更复杂的权限,可以在UserDocuments多对多表中使用一个额外字段来指定权限的类型。

    虽然您的问题非常详细,但实际上缺少一些上下文。
    什么定义了用户有权限访问的文档?用户只能编辑自己的文件吗?这里有基于角色的机制吗?它是否更面向MAC(即用户可以看到安全级别)?数据是否有定义属性(例如部门)

    所有这些问题加在一起可能会给出一个更好的画面,并给出更具体的答案

    如果文档是由特定用户“拥有”的,那么很简单——为文档设置一个“所有者”字段。然后,查询用户拥有的所有文档。
    类似地,如果可以预定义具有访问权限的命名用户(或角色)列表,则可以查询文档、授权用户/角色列表和用户(或其角色)之间的关联列表。
    如果用户根据其部门(或其他类似文档的属性)获得权限,则可以对此进行查询。
    同样,您可以查询安全级别等于或低于用户权限级别的所有文档。 如果这是动态工作流,则每个文档通常应标记其当前状态和/或下一个预期步骤;哪些用户可以执行下一步只是另一个特权/角色(如上所述)。
    然后,当然,你会想在所有这些文件和公共文件之间建立一个联盟


    顺便说一句,如果我没有说清楚,这不是一个简单的问题-帮你自己一个忙,找到预构建的基础设施来为你做这件事。即使以简化授权模式为代价

    你可能对阅读感兴趣。它总结了RubyonRails的所有授权插件,我相信它将帮助您找到解决方案(尽管本文是关于Rails插件的,但是这些概念很容易在Rails之外导出)

    Steffen还构建了自己的插件,名为“声明性授权”,它似乎符合您的需求,IMHO:

    • 一方面,您定义了角色(如“访问者”、“管理员”…)。您的用户与这些角色关联(在多对多关系中)。您可以将这些角色映射到权限(同样是在多对多关系中)。每个特权都链接到给定的上下文。例如,角色“访问者”可能具有“读取文档”权限。在本例中,“read”是特权,它应用于“documents”上下文。
      • 注意:在Steffen的插件中,您可以定义角色的层次结构。例如,您可能希望“全局管理员”角色包括“文档管理员”角色以及“评论管理员”角色等
      • 您还可以定义权限的层次结构:例如,“管理”权限可以包括“读取”、“更新”、“添加”和“删除”权限
    • 另一方面,您可以根据特权和上下文对应用程序进行编码,而不是根据角色。例如,显示文档的操作只应检查用户是否具有在“文档”上下文中“读取”的权限(无需检查用户是否具有“访问者”角色或任何其他角色)。这大大简化了代码,因为大部分授权逻辑都是在其他地方提取的(甚至可能是由其他人定义的)
    用户角色定义和应用程序级权限定义之间的这种分离保证了代码不会在每次定义新角色时更改。例如,以下是控制器中访问控制的简单程度:

    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>
    
    就这些!您现在可以获得允许用户更新的所有文档,如下所示:

    role :document_author do
      has_permission.on :documents do
        to :manage
        if_attribute :author => is {user}
      end
    end
    
    Document.with_permissions_to(:update)
    
    由于“管理”权限包括“更新”权限,因此将返回其作者为当前用户的文档列表

    当然,并不是每个应用程序都需要这种级别的灵活性。。。但你的可能

    Document.with_permissions_to(:update)