【问题标题】:Spring Security and ABAC (Attribute Based Access Control)Spring Security 和 ABAC(基于属性的访问控制)
【发布时间】:2015-11-07 09:32:25
【问题描述】:

我们有一个中型业务应用程序,我们大量使用 Spring Security 角色和权限 (RBAC),并大量使用为某些实例打开和关闭角色以及隐藏在 SpEL 中的规则@PreAuthorize 标签内。

我认为我们实际上已经实现了(不知道是 ABAC)。 XACML 看起来非常复杂和臃肿,所以我不热衷于这里的答案:

How to change Spring Security roles by context?

有没有人在没有 XACML 的情况下完成了轻量级的 ABAC 实现?我希望这能让我们分离关注点,因为域对象只是做@PreAuthorize(WRITE) 等,我们的授权策略将与之分离。

根据我的阅读,ABAC 的基本原理非常简单。如果当前 Principal 对给定的 Subject 具有该权限,则您有一个 Action(非常类似于 Permission)和一个解决机制。

我知道AccessDecisionVoter 大致是正确的界面类型,但我认为它不是用于对权限进行投票。然而,用类似的实例来实施我们的授权政策似乎非常有吸引力。

抱歉这个漫无边际的问题!基本上我对 ABAC 很感兴趣,但想避免自制,但担心当我们需要 Cessna 时 XACML 是大型喷气式飞机。

【问题讨论】:

  • 是什么让您认为西飞是拖拉机的车轮?实现起来很简单
  • Spring Security 和 XACML 通过 Axiomatics spring 插件直接集成
  • 嗨,David,查看 XACML 源代码非常冗长和复杂。我玩过 Java 中的规则是什么样子的,它很简单,我们已经具备了这种技能,它是编译时检查的……而且 Axiomatics 似乎是 XACML 上唯一真正活跃的工作。我可以想象 XACML/Axiomatics 对大型企业有好处,但那不是我们。抱歉,“拖拉机车轮”判断错误。当我们需要塞斯纳时,大型喷气机?我将编辑我的问题。

标签: spring-security rbac xacml abac


【解决方案1】:

您的目标似乎有两件事:

  1. 外部授权,您希望将访问控制策略移出代码(或至少移到代码的中心位置,而不是分散在 Spring 代码中)
  2. 基于属性的授权,您希望使用比角色和权限更丰富的属性

我不太确定 (2),因为在我的书中,“如果当前委托人拥有该权限,则“行动和解决机制”仍然是 RBAC。您是否还有其他条件需要作为访问授权决策的依据?用户的位置、一天中的时间、数据库中某些数据的值、正在操作的资源的属性等?如果是这样,我们就会误入 ABAC 世界。无论哪种方式,我都会说 RBAC 是 ABAC 的一个子集,因为角色只是一个属性。

现在,对于(1),一般模式是首先集中授权引擎并使用Spring注解来调用这个authz。访问决策的引擎。你有两个选择:

  • 嵌入式身份验证。引擎:库实现引擎并由代码调用,就像 Java 函数一样。可以是 XACML 引擎,也可以是您自己的 RBAC/ABAC 实现
  • 作为网络服务:基于网络的(微)服务回答访问控制决策问题。可以是 XACML 引擎,也可以是您自己的 RBAC/ABAC 实现

为了让基于 Spring 的代码调用这个 authz。引擎,一种方法是编写自己的 Spring Security 投票器。我发现更容易的另一种方法是编写您自己的基于 Spring 表达式语言的表达式,然后您可以使用现有的 @PreAuthorize、@PostAuthorize、@PreFilter 和 @PostFiler、sec:authorize 标记甚至从拦截 url 调用条件。

这是我在Spring Security XACML PEP SDK 工作时使用的。即使您决定不将 XACML 用于访问决策策略或请求/响应通信,该方法也应该同样有效。

【讨论】:

  • 非常感谢您的详细回答。尝试解释为什么我认为我可能需要 ABAC:一条规则是“如果 adminRole 或 (!this.submitted and !this.historic and ((this.confidential and powerRole) or (!this.confidential and inASetOfPeopleResponsibleForThisObject)) 抱歉伪代码和晦涩的域。我完全同意部分解决方案是 RBAC,但与依赖于对象关系的角色相比,我们的“静态”角色非常少。
  • 是的,您所描述的绝对超出了 RBAC。我认为我上面提到的方法仍然适用于您。
  • 谢谢斯里吉斯。如果你会那么好心,最后一点理智检查/手握。有没有你知道的开源 ABAC 引擎?合理地编写我们自己的简单微框架?我已经拼凑了一个概念证明,但这总是很容易;)
  • .. 如果轻量级 ABAC 实现不特意使 XACML 不兼容,那就太好了,这样确实发现他们需要更强大的东西的人有更简单的升级路径。跨度>
【解决方案2】:

可以在此处找到不使用 XACML 的非常好的方法。这基本上就是你想要的。 ABAC 上的一种轻量级方法,无需实现 XACML。 https://dzone.com/articles/simple-attribute-based-access-control-with-spring

【讨论】:

  • 我们真的很想摆脱 SpEL(这样我们就可以更轻松地重构等)。作为我们的自制方法非常有偏见,但我们的规则是纯 Java,每个都是一个服务,因此它被加载和注册,规则使用泛型(如此强类型)......然后只需 PreAuthorize(Action.WRITE) 方法(不是 SpEL 只是一个指向规则的标记)
  • @salk31 听起来很有趣。你是如何摆脱SpEL的?您是否覆盖了 PreAuthorize 注释?您如何评估 Java 规则?很抱歉有很多问题。我只是好奇,因为我目前正在尝试实现类似的东西。
  • 我们仍在迁移,所以我们的 SpelExpressionParser 将我们的动作名称包装在 hasPermission(this ....) 中,然后我们注册实现 String getAction、Class getType 和 boolean permit(AuthContext context) 的服务。 ..如果你有兴趣,我可以尝试把它推到github上,没有什么很聪明的......
【解决方案3】:

我知道这个问题很老了,但最近我们需要类似的 ABAC 权限实现。起初,我试图找到能够满足我们需求的现有东西,但一切似乎都太过分了,而且很难使用。

所以我想出了一个名为 jaclp 的非常简单的库,可以在 GitHub 上找到它。它支持经典的RBAC 方法和更复杂的ABAC,例如可用于作为资源的JPA 实体。集成和设置应该相当简单。

其中一个缺点是目前只能以编程方式定义权限。我计划介绍将从中加载权限规则的配置文件。 jaclp 库现在只支持在代码中定义的静态权限规则,这意味着您不能动态加载权限规则,例如从数据库中加载。

示例用法:

// Applying permissions on REST endpoints

@GetMapping("groups/{id}")
@PreAuthorize("hasPermission(#id, 'group', 'viewDetail')")
public GroupDetailDTO getGroupDetail(@PathVariable long id) {
    return this.groupService.getGroupDetail(id);
}

// Defining role with both RBAC and ABAC approach

Role userRole = RoleBuilder.create("user")
        .addAllowedRule("group",
                (UserDetails user, GroupEntity group) -> group.isPublic(), 
                "viewDetail")
        .addAllowedRule("group", "viewAll")
        .build();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 2018-11-28
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多