我的一位同事向我提出了一个关于StackOverflow的有趣问题,并由于我在Spring方面的经验,建议我回答一个很好的问题。
问题是:“ 如何基于使用注释在REST中创建资源的用户来授权特定资源 。”
要点是:
我想做的是创建一个名为@Authorize的注释,并将其用于需要用户授权才能执行某些操作的用户(此时用户已通过身份验证)。 例如。 我有一个带有getOrder()
方法的订单服务。 我只希望创建此订单的用户访问它。
我对StackOverflow的回答
为了对Java中的方法实现授权控制,我强烈建议使用带有 Spring Security API 的可扩展访问控制标记语言(XACML)实现的Spring Security。
Spring安全
Spring Security提供了两种主要方法来保护对方法的访问:
- 预授权 :这允许在允许执行该方法之前检查某些条件/约束。 无法验证这些条件将导致无法调用该方法。
- 后授权 :允许在方法返回后检查某些条件/约束。 与预授权检查相比,此方法使用较少,但可用于在复杂的互连业务层方法周围,特别是在与该方法返回的对象相关的约束周围,提供额外的安全性。
例如,说访问控制规则之一是用户在能够调用方法getEvents()之前具有ROLE_ADMIN权限。 在Spring Security框架中执行此操作的方法是使用PreAuthorize批注,如下所示:
public interface Sample { ...
@PostAuthorize("hasRole('ROLE_ADMIN')")
Event getEvent(); }
本质上,Spring Security使用运行时面向方面编程(AOP)切入点在对该方法提出建议之前执行,并在ossaccess.AccessDeniedException
指定的安全性约束的情况下抛出ossaccess.AccessDeniedException
。
在本文档的第27.3节中可以找到有关Spring Security的方法级别安全性的更多信息 。
可扩展访问控制标记语言(XACML)– ABAC的策略语言
Spring Security通过基于表达式的访问控制在实现访问控制方面做得很出色,但是基于属性的访问控制(ABAC)允许对访问进行更细粒度的控制,这是美国国家标准技术研究院的推荐。
为了解决基于角色的访问控制(RBAC)的局限性,NIST提出了一种称为ABAC(基于属性的访问控制)的新模型。 在ABAC中,您现在可以使用更多的元数据/参数。 例如,您可以考虑:
- 用户的身份,角色,职务,位置,部门,出生日期…
- 资源的类型,位置,所有者,价值,部门...
- 上下文信息,例如用户在资源上尝试执行的操作的时间
所有这些都称为属性。 属性是ABAC的基础,因此是名称。 您可以将这些属性组合到策略中。 政策有点像ABAC的秘密武器。 策略可以授予和拒绝访问。 例如:
- 如果员工和记录位于同一区域,则员工可以查看记录
- 在下午5点至早上8点之间拒绝访问阅读记录。
策略可用于表达高级方案,例如
- 职责分工
- 基于时间的约束(请参见上文)
- 基于关系的访问控制(请参见上文)
- 委派规则委派Bob访问Alice的文档。
有两种主要语法可用于编写策略:
- 基于XACML的缩写授权语言(ALFA)
- 可扩展访问控制标记语言(XACML)
ABAC还带有一个体系结构,用于定义如何评估和执行策略。
该体系结构包含以下组件:
- 策略执行点(PEP):这是保护您要保护的API /应用程序的组件。 PEP拦截流,对其进行分析,然后向PDP发送授权请求(请参见下文)。 然后,它会收到执行的决定(许可/拒绝)。
- 策略决策点(PDP)会收到授权请求(例如Alice可以查看记录#123?),并根据已配置的策略集对其进行评估。 最终,它会做出决定,并将其发送回PEP。 在评估过程中,PDP可能需要其他元数据,例如用户的职务。 为此,它可以求助于策略信息点(PIP)
- 策略信息点(PIP)是PDP与基础数据源(例如LDAP,数据库,REST服务)之间的接口,其中包含有关用户,资源或其他方面的元数据。 您可以使用PIP检索PDP在运行时可能需要的信息,例如风险评分,记录的位置或其他。
XACML的实现
全面披露–我在XACML技术委员会工作,并为Axiomatics工作, Axiomatics是实施XACML的动态授权的提供者。
Axiomatics为他们的Axiomatics Policy Server提供了一个Spring Security SDK,它提供了四个表达式,可用于查询PDP,作为保护方法调用的一部分
- xacmlDecisionPreAuthz,使用
@PreAuthorize
- xacmlDecisionPostAuthz,使用
@PostAuthorize
- xacmlDecisionPreFilter,使用
@PostFilter
- xacmlDecisionPostFilter,使用
@PreFilter
这些方法的确切签名如下:
-
xacmlDecisionPreAuthz(Collection<String> attributeCats,
Collection<String> attributeTypes, Collection<String> attributeIds,
ArrayList<Object> attributeValues) -
xacmlDecisionPostAuthz(Collection<String> attributeCats,
Collection<String> attributeTypes, Collection<String> attributeIds,
ArrayList<Object> attributeValues) -
xacmlDecisionPreFilter(Collection<String> attributeCats, Collection<String>
attributeTypes, Collection<String> attributeIds, ArrayList<Object>
attributeValues) -
xacmlDecisionPostFilter (Collection<String>
attributeCats, Collection<String> attributeTypes, Collection<String>
attributeIds, ArrayList<Object> attributeValues)
有关XACML实现的完整列表,可以在Wikipedia上查看此列表 。
翻译自: https://www.javacodegeeks.com/2018/07/authorizing-resources-created.html