存储库查询的Spring安全授权

时间:2017-03-03 01:27:53

标签: spring-boot spring-security authorization spring-data

如果我有一个存储在表格中并通过url / orders / {id}公开的订单列表,我想通过更改网址中的路径id来限制委托人访问订单, Spring Security可以帮助我查询Spring Data JPA存储库。

基于Spring Security 4 youtube视频: -

interface OrderRepository extends Repository<Order, Long> {

    @Query("select o from Order o where o.id = ?1 and o.from.id = ?{#principal.id}  ")
    Optional<Order> findOrder(long id);
}

这是最佳做法吗?理想情况下,我想使用Spring Data方法名称功能,并避免在这种情况下重写Query。

1 个答案:

答案 0 :(得分:0)

我认为您正在寻找的是来自Spring security的@PreAuthorize或@PostAuthorize。它们是春季方法级安全性的注释。它们将允许您根据角色和其他属性进行限制。

interface OrderRepository extends Repository<Order, Long> {

@PreAuthorize("hasRole('ROLE_ADMIN')") // Allows only users with admin privileges
@Query("select o from Order o where o.id = ?1 and o.from.id = ?{#principal.id}  ")
Optional<Order> findOrder(long id);

}

https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/

编辑:

如果您希望仅在当前经过身份验证的用户与订单来源相关联时才返回订单。

@PostAuthorize("returnObject.from == authentication.name")
Optional<Order> findOrder(long id);

您可以将spring表达式语言与@PreAuthorize @PostAuthorize注释一起使用。

http://docs.spring.io/spring-security/site/docs/current/reference/html/el-access.html

希望这有帮助

编辑2:您可以使用@PreFilter和@PostFilter来过滤集合。

实施例

@PostFilter("filterObject.from == authentication.name")
List<Order> findOrder(long id);

这将在列表中运行,并且仅返回其中from是当前经过身份验证的用户的订单。您还可以组合表达式。

@PostFilter("hasRole('ROLE_ADMIN') or filterObject.from == authentication.name")
List<Order> findOrder(long id);

这将检查当前经过身份验证的用户是否具有ROLE_ADMIN角色。如果用户具有该特权,则未返回的列表将返回,否则它将过滤并仅返回“from”与当前经过身份验证的用户关联的那些订单。