如何使用注解根据在 REST 中创建资源的用户授权特定资源

How to authorize specific resources based on users who created those in REST, using annotations

我不太理解 Java 将保留策略作为 RUNTIME 的注释。我想要做的是创建一个名为 @Authorize 的注释,并将其用于需要用户授权才能执行某些操作的方法(此时用户已经通过身份验证)。 例如。我有一个带有 getOrder() 方法的订单服务。我只希望创建此订单的用户可以访问它。 `

public void getOrder(User user) {
   //current code does something like this
   if(order.getCreatedBy().equals(user)) {
     //then proceed. 
}

} `

我不想将此逻辑与业务逻辑混合。相反,我希望有这样的东西 - `

@Authorize
public void getOrder(User user) {
   //business logic
}

` 有几种方法,但并非所有方法都需要此类授权。有人能解释一下我怎样才能把这些碎片拼在一起吗? 在这一点上我不明白的是 AnnotationProcessor 会如何帮助我,因为它在编译时发挥了它的魔力。据我所知,它会帮助我在编译时生成一些代码,但我不知道如何使用生成的代码。我浏览了很多关于 AnnotationProcessors 的例子,但我仍然遗漏了一些东西。 到目前为止,这些链接帮助我理解了注释处理 -

http://hannesdorfmann.com/annotation-processing/annotationprocessing101 https://equaleyes.com/blog/2017/09/04/annotation-processing/

即使我使用反射,我应该把反射逻辑放在哪里?它是否与我想要实现的目标适得其反?

在这一点上,我也对其他解决方案持开放态度,这些解决方案不涉及注释,但会帮助我分离出具有此类资源特定授权的业务逻辑。

要对 Java 中的方法实施授权控制,我强烈建议 Spring 使用可扩展访问控制标记语言 (XACML) 实现的安全性一个 Spring 安全 API.

Spring 安全性

Spring 安全性提供了两种主要方法来保护对方法的访问:

  • 预授权:这允许某些 conditions/constraints 在允许执行该方法之前进行检查。未能 验证这些条件将导致无法调用 方法。
  • 后授权:这允许某些 conditions/constraints 在方法 returns 之后进行检查。这较少使用 预授权检查,但可用于提供额外的安全性 围绕复杂的互连业务层方法,尤其是 围绕与方法返回的 object 相关的约束。

例如,访问控制规则之一是用户在能够调用方法 getEvents() 之前具有 ROLE_ADMIN 权限。在 Spring 安全框架内执行此操作的方法是使用如下所示的 PreAuthorize 注释:

public interface Sample { ... 
@PostAuthorize("hasRole('ROLE_ADMIN')") 
Event getEvent(); } 

本质上 Spring 安全性使用运行时面向方面编程 (AOP) 切入点在方法建议之前执行,如果不满足指定的安全约束,则抛出 o.s.s.access.AccessDeniedException

更多关于 Spring 安全方法级别安全的信息可以在 documentation 的第 27.3 节找到。

可扩展访问控制标记语言 (XACML) - ABAC 的策略语言

Spring Security 通过其基于表达式的访问控制在实现访问控制方面做得很好,但基于属性的访问控制 (ABAC) 允许更细粒度的访问控制,并被美国国家标准协会推荐和技术。

为了解决基于角色的访问控制 (RBAC) 的局限性,NIST 提出了一种称为 ABAC(基于属性的访问控制)的新模型。在 ABAC 中,您现在可以使用更多元数据/参数。例如,您可以考虑:

  • 用户的身份、角色、职务、地点、部门、日期 出生...
  • 资源的类型、位置、所有者、价值、部门...

  • 上下文信息,例如一天中用户正在执行的操作的时间 尝试资源

所有这些都称为属性。属性是 ABAC 的基础,因此得名。您可以 assemble 这些属性到策略中。策略有点像 ABAC 的秘方。策略可以授予和拒绝访问权限。例如:

  • 如果员工和记录在同一地区,则员工可以查看记录
  • 拒绝访问下午 5 点到早上 8 点之间的阅读记录。

策略可用于表达高级场景,例如

  • 职责分离
  • time-based 约束条件(见上文)
  • relationship-based 访问控制(见上文)
  • 委托规则委托 Bob 访问 Alice 的文档。

有 2 种主要语法可用于编写策略:

ABAC 还附带一个架构来定义如何评估和执行政策。

架构包含以下组件:

  • 策略执行点 (PEP):这是组件 保护您要保护的 API / 应用程序。 PEP拦截 流程,对其进行分析,并向 PDP 发送授权请求 (见下文)。然后它收到一个决定(Permit/Deny),它 强制执行。

  • 策略决策点 (PDP) 收到授权请求 (例如,Alice 可以查看记录 #123 吗?)并根据集合对其进行评估 它已配置的策略。它最终达到一个 它发送回 PEP 的决定。评估期间 过程中,PDP 可能需要额外的元数据,例如用户的工作 标题。为此,它可以求助于政策信息点 (PIP)

  • 策略信息点 (PIP) 是 PDP 之间的接口 和基础数据源,例如LDAP、数据库、REST 服务 其中包含有关用户、资源或其他的元数据。您可以使用 PIP 用于检索 PDP 在运行时可能需要的信息,例如风险 分数、记录的位置或其他。

XACML 的实现

完全披露 - 我在 XACML 技术委员会工作,并为 Axiomatics 工作,这是一个实现 XACML 的动态授权提供商。

Axiomatics 为其 Axiomatics Policy Server 提供了一个 Spring 安全 SDK,它提供了四个可用于查询 PDP 的表达式,作为保护方法调用的一部分

  1. xacmlDecisionPreAuthz,用 @PreAuthorize
  2. 调用
  3. xacmlDecisionPostAuthz, ca以 @PostAuthorize
  4. 为首
  5. xacmlDecisionPreFilter,用 @PostFilter
  6. 调用
  7. xacmlDecisionPostFilter,用 @PreFilter
  8. 调用

这些方法的确切签名如下:

  1. xacmlDecisionPreAuthz(Collection<String> attributeCats, Collection<String> attributeTypes, Collection<String> attributeIds, ArrayList<Object> attributeValues)
  2. xacmlDecisionPostAuthz(Collection<String> attributeCats, Collection<String> attributeTypes, Collection<String> attributeIds, ArrayList<Object> attributeValues)
  3. xacmlDecisionPreFilter(Collection<String> attributeCats, Collection<String> attributeTypes, Collection<String> attributeIds, ArrayList<Object> attributeValues)
  4. xacmlDecisionPostFilter (Collection<String> attributeCats, Collection<String> attributeTypes, Collection<String> attributeIds, ArrayList<Object> attributeValues)

对于 entire list of XACML implementations, you can check this list on Wikipedia.