【问题标题】:Authorization Service -- returning a list of authorized resources授权服务——返回授权资源列表
【发布时间】:2012-11-18 23:22:18
【问题描述】:

检索用户有权访问的所有资源列表的推荐方法是什么?

在我见过的许多示例中,授权被放置在一个单独的服务中——通常一个公开类似于 isAuthorized() 的方法,该方法可用于单个查询(“用户是否有权使用资源 ABC? ") 以及批量查询(“用户是否有权使用以下任何资源列表?”)。

虽然授权逻辑存在于授权服务中,但授权策略的执行保留在应用程序本身中(例如,用于实际实施的业务逻辑层根据授权服务的结果访问资源;或表示层根据授权服务的结果显示/隐藏各个选项等)。

例如,如果我的数据访问层有可能返回的数十亿“资源”,那么执行此操作的首选方法是什么?我的业务逻辑层是否查询所有数据(通过网络传递所有数据),然后将该巨大列表转发到授权服务(再次通过网络),只得到一个巨大的“允许/拒绝”列表发回业务逻辑?显然这听起来不太对。

在这种情况下,我们不能对数据访问、授权逻辑和业务逻辑进行“干净”分离吗?我是否应该要求我的数据访问层只向我返回用户有权访问的所有资源的列表,这最终可能被实现为简单的数据库连接,但随后需要一些用于确定谁的逻辑可以在什么条件下访问哪些资源(即授权策略)嵌入数据访问代码中,因此这些策略将分布在我的代码库中(例如,某些授权逻辑将在我的数据访问中层,有些会在我的授权层等)?

也许性能胜过“干净”的架构,但有更好的方法吗?

【问题讨论】:

  • 我正在开发一个大型遗留应用程序,我面临着类似的难题。 “大型结果集”场景很棘手,我绝对不认为这不是 sJhonny 暗示的问题。虽然 所有 记录的结果集可能不是一个好的设计,但如果您想提供记录数或页数,您仍然会遇到问题(而一个好的设计会我>)。如果您的数据层是基于不同的技术(例如 SQL 存储过程)构建的,这将变得更加困难。即使您承认重复您的授权逻辑,它也是一种不同的语言!

标签: service architecture authorization


【解决方案1】:

我对你的问题没有明确的答案,但我也许可以提供一些建议-

  • 你问

    我的业务逻辑层是否查询所有数据,然后转发 那个巨人名单上授权服务,只是为了得到一个巨人 发送回业务逻辑的“允许/拒绝”列表?

好吧,对我来说,这似乎不太可能发生。您能想到一种情况,您希望将所有可用记录呈现给用户吗?您想要进一步过滤这些记录(即按类型、日期等)不是更合理吗,并且您可能还想对它们进行分页以便用户获得一口大小的结果集。
  • 再加上您很可能只会将记录的标识符传入和传出您的服务这一事实,您可能会发现这种方法对您来说是可行的。

  • 另外请注意,将您的授权逻辑作为“服务”并不一定意味着它必须驻留在不同的机器上;您可以将它实现为一个单独的逻辑模块,并且仍然让它在同一台机器上运行(如果您愿意,可能与您的应用程序在同一进程上),从而避免网络流量问题。

  • 您认为将授权作为数据访问的一部分实施可能很棘手,这是正确的。但是,有一些基础设施工具可以帮助您。例如-oracle 的virtual private database(n)hibernate filters,我相信还有其他的。

同样,这些不是完整的答案,但它们可能会引导您找到适合您的解决方案。
我建议你谷歌“授权框架+ [你最喜欢的编程语言]”;我敢肯定有人已经这样做了:)

【讨论】:

    【解决方案2】:

    我有一个萌芽的想法,不是基于任何实践经验,但乍一看似乎是合理的。

    为什么我们有授权服务?我的主张是,我们具有该服务的某些功能,因为我们的数据源没有完成完整的工作。如果我们仅使用 RDBMS 数据库作为数据源,那么该数据库可以监管主要的授权类别。我们可以针对视图工作并授予访问这些视图的权限,从而根据需要保护表和列。剩下的就是这样的一套规则

    可以向 a) 显示员工的工资信息。员工, 乙)。他们的经理和二线经理,c)。人力资源部成员 薪酬团队。

    我相信这样的授权规则具有业务语义,最好由授权服务实现,并且该服务的表达方式是业务对象:

     can This employee see That employee's salary?
    

    它不是以表、行和列的形式表示,而是以更粗略的、对业务有意义的粒度表示。实现这一点需要构建一个表达授权规则的数据模型,严格来说这是业务逻辑,我们只是选择重构为授权服务来封装实现。

    将此与以视图、表和列表示的细粒度实体授权进行对比。我的主张是这正确地属于数据源,如果我们的数据源不能或没有实现它,那么我们需要在我们的数据访问层中实现它。 DAO“知道”他们使用哪些视图/表,并且可能还知道代表谁运行请求的 id,因此决定是否允许访问。

    松散地说:DAO 有 SQL,所以知道实体,所以可以决定。 (是的,某些后端可能没有 SQL,但 DAO 是了解正在检索的内容的对象。)它可以通过一种方法来丰富它,以列出给定用户允许其哪些访问方法。

     CustomerDAO.whatIsAuthorised("joeCoder") => READ, QUERY
    
     CustomerDAO.whatIsAuthorised("phb") => READ, QUERY, UPDATE
    

    【讨论】:

      【解决方案3】:

      身份验证最好外部化。授权通常过于依赖应用程序而无法外部化。它可能适用于小型系统。但是对于大型系统,您会遇到预期的扩展问题。

      另一件事是返回大量数据集。在我看来,这更适合报告。因此,将具有不同要求的第一个流程模块与报告模块分开,因为在业务流程中您需要集中数据以及报告大量数据和抽象。

      授权不是一层。这是一个方面。如果您不至少用适当的模拟替换它,则应用程序可能在没有层的情况下无法工作。但是,如果您删除方面,则运行应用程序应该不会有问题。也许您的程序不会记录任何内容,或者您​​将能够看到比您允许看到的更多的数据,但它仍然可以工作。

      那么授权是否应该从应用程序域外部化?不。它应该与业务逻辑分开吗?是的。正确的机制:方面(AspectJ、Proxy-Pattern、Template-Class-Pattern)。这是我的一般建议。

      我对业务流程中的“海量数据”的特别建议是:尝试正确划分您的领域模型,以减少集中数据(主题“可用性”或“用户体验”)。然后回到我的一般建议。

      如果您必须在业务流程中处理大量数据:请使用“让它工作,让它正确,让它快速”的最后一点。将其视为对特殊数据请求的优化,这些请求可能会或预计会很慢。在这种情况下,使用特殊的 sql 查询、预加载、缓存等。DAO-Layer 可能是正确的位置、缓存方面或 DAO-Layer 的优化方面,它覆盖“工作缓慢”的替代实现 - 实现快。

      我提出的建议是指正常的业务用例。我不是在谈论大数据或报告。正如我提到的,这些行业有不同的要求。

      【讨论】:

        猜你喜欢
        • 2016-05-21
        • 2014-07-09
        • 1970-01-01
        • 2023-03-25
        • 2017-11-10
        • 2019-04-05
        • 2020-10-08
        • 2018-05-07
        • 2019-10-27
        相关资源
        最近更新 更多