存储库查询的 Spring Security 授权

Posted

技术标签:

【中文标题】存储库查询的 Spring Security 授权【英文标题】:Spring Security Authorisation for Repository Query 【发布时间】:2017-07-22 23:34:16 【问题描述】:

如果我有一个存储在表中并通过 url /orders/id 公开的订单列表,并且我想通过更改 url 中的路径 id 来限制委托人访问订单,Spring 如何安全性帮助我查询 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 方法名称功能并避免在这种情况下重写查询。

【问题讨论】:

【参考方案1】:

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

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);

您可以使用带有@PreAuthorize @PostAuthorize 注释的springs 表达式语言。

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);

这将遍历列表并仅返回来自当前经过身份验证的用户的订单。您还可以组合表达式。

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

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

【讨论】:

@PreAuthorize 如何按每个用户而不是按角色进行授权? @aprofromindia 编辑了我的帖子。 PostAuthorize 将检查返回的 Order 对象的 from 成员变量与当前认证的用户。 酷我们如何为 findAll() 授权实现这个逻辑。我不想使用@PostFilter() 过滤整个列表。 我更新了我的回复,但刚刚读到您不想使用 PostFilter。我不确定没有 PostFilter 的方法

以上是关于存储库查询的 Spring Security 授权的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security sec:使用 Java Config 授权标签

spring-security-oauth2 替代品

用于非授权连接的 Spring Security REST Api

在不使用 Spring Security OAuth 的情况下实现 oauth2 授权服务器

Spring Security 结合 Spring 存储库来保护和验证网站的各个部分

如何使用 Spring Security 在代码中获取用户的授权凭据?