8

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

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

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

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

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

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

4

3 回答 3

1

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

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

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

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

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

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

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

于 2015-05-09T17:29:00.847 回答
0

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

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

员工的工资信息可以显示到 a)。雇员,b)。他们的经理和二线经理,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
于 2013-04-19T10:15:34.827 回答
0

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

  • 您问

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

好吧,对我来说,这似乎不太可能发生。您能想到一种情况,您希望将所有可用记录呈现给用户吗?您希望进一步过滤这些记录(即按类型、日期等)不是更合理吗,并且您可能还希望对它们进行分页以便用户获得一口大小的结果集。

  • 再加上您很可能只会在服务之间传递记录的标识符这一事实,您可能会发现这种方法对您来说是可行的。

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

  • 您认为将授权作为数据访问的一部分实施可能很棘手的观察是正确的。但是,有一些基础设施工具可以帮助您。例如 - oracle 的虚拟私有数据库(n)hibernate 过滤器,我相信还有其他的。

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

于 2012-12-02T22:00:38.650 回答