存储库查询的 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 REST Api
在不使用 Spring Security OAuth 的情况下实现 oauth2 授权服务器