基于表达式的访问控制的细粒度授权


今天,我们将回顾基于表达式的访问控制(EBAC),基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)之间的差异,并更加关注EBAC。

什么是基于表达式的访问控制?
简单地说,基于表达式的访问控制是使用表达式来编写授权。基于表达式的访问控制(EBAC)目前最常与使用Spring表达式语言表达式来编写授权相关联。
在Spring Security 3.0中,除了简单使用配置属性和访问决策之外,还引入了使用Spring EL表达式作为授权机制的能力。
然而,使用表达式进行访问控制是不是仅限于Spring Security,可要求更大的社区认可在授权中使用表达式作为基于表达式的访问控制(EBAC),因为它与其他形式的访问控制具有独特的不同,因为它能够让您实现其他访问控制的形式,如RBAC和ABAC
EBAC的其他示例包括MapR中访问控制表达式(ACE)Windows中的动态访问控制。还有其他一些,例如PHP Framework Symfony

EBAC=ABAC?
基于表达式的访问控制(EBAC)是否等同于基于属性的访问控制(ABAC)?不,但ABAC可以通过EBAC实施。根据NIST特刊800-162,这是ABAC的高级定义:
基于主题的指定属性,对象的指定属性,环境条件以及根据这些属性和条件指定的一组策略,授予或拒绝主体对对象执行操作的请求的访问控制方法
考虑到这一点,我们可以使用表达式语言编写自己的表达式语言,例如基于Spring Expression Language的表达式,然后可以使用现有的@PreAuthorize,@ PostAuthorize,@ PreFilter和@PostFiler,sec:authorize标签调用,甚至可以通过intercept-url 条件。

EBAC=RBAC?
不,EBAC不等同于RBAC,但RBAC内置于某些表达语言,如Spring EL。例如,有这两个常见的表达式允许我们轻松实现RBAC:

  • hasRole([作用])
  • hasAnyRole([基于role1,基于role2])

但是,在编写细粒度授权规则时,我们很容易开始编写超出RBAC粒度级别的表达式。

网络安全表达式
EBAC实现(例如Spring Security)允许我们保护URL。表达式应评估为true或false,定义是否授予访问权限。基于Java配置中的userID限制RESTful应用程序中的访问的示例:

http
.authorizeRequests()
.antMatchers("/user/{userId}/**").access("@webSecurity.checkUserId(authentication,userId)")
...

方法安全表达式
方法安全性比“允许或拒绝”更复杂。
例如,在Spring Security中,有四个注释使表达式属性执行调用前和调用后授权检查,并支持过滤提交的集合参数或返回值。
@PreAuthorize是最常用的,它决定是否可以实际调用方法。
@PostAuthorize是一种不常用的注释,在调用方法后执行访问控制检查。
使用@PostFilter,Spring Security会遍历返回的集合并删除所提供表达式为false的所有项目。
@PreFilter允许我们在方法调用之前进行过滤,但这种情况不太常用。

下面我们有一个将PreAuthorize与@PostFilter相结合的示例,以获得更细粒度的安全性:

@PreAuthorize("hasRole('USER')")
@PostFilter(
"hasPermission(filterObject, 'read') or hasPermission(filterObject, 'admin')")
public List<contact> getAll();

何时使用基于表达式的访问控制(EBAC)?
如果我们需要的安全性需要比简单的访问控制列表(ACL)更精细,那么我们需要使用EBAC。我们如何决定实施EBAC是我们可以获得的资源。例如,在使用Spring Security的组织中,为什么不使用他们的Spring EL?同样,如果我们有MapR,那么我们将使用他们的访问控制表达式。
在其他情况下,为了满足组织的需要,可能需要以优惠语言编写我们自己的表达语言以实现EBAC。当然,我们花时间做这件事的原因是为了让我们能够根据我们想要的条件实现我们想要的任何类型的访问控制。一旦我们有足够的表达语言来实现这一目标,另一个好处是我们不太可能依赖其他人 - 无论是商业现货产品还是开源产品。

结论
各种软件都能够使用表达式编写授权,例如MapR,Windows,当然还有Spring Security。如果可以使用表达式完成细粒度的访问控制,我将其称为 - 并建议您将其称为 - 基于表达式的访问控制(EBAC)。通过命名,我们更有可能使用它来保护我们的系统而不是传统的RBAC。这很好,因为细粒度的访问控制,如果操作得当,更有可能防止漏洞。