让我们假设下面的基于Spring JPA的存储库支持QueryDsl。
@Repository
public interface TeamRepository extends JpaRepository<Team, Long>, QuerydslPredicateExecutor<Team> {
}
应用程序在服务层中使用 * 访问控制列表(ACL)* 来检查单个资源的权限,例如使用@PreAuthorize(hasPermission(#id, 'Team', 'READ')
。
我想允许一个用户请求所有他有读权限的团队。我试着使用@PostFilter(hasPermission(filterObject, 'READ')
,只要我使用Iterable<Team> findAll(Predicate predicate)
就能很好地工作。但是当我试着使用分页时,@PostFilter
似乎抛出了一个异常。
java.lang.IllegalArgumentException: Filter target must be a collection, array, or stream type, but was Page 1 of 0 containing UNKNOWN instances
官方的Spring安全参考文档建议使用支持分页的@Query
编写一个自定义查询。
如何编写这样一个支持QueryDsl的 predicate、分页和基于权限的过滤的复杂查询?
于2020年3月24日进场
在另一个forum中,我遇到了以下基于QueryDsl的方法:ACL tables被Map为@Immutable
JPA实体,而不是本地或自定义查询,从而生成Q类,并使用它们手动过滤权限。
@Entity
@Immutable
@Table(name = "acl_object_identity")
public class AclObjectIdentity implements Serializable {
...
}
如何使用一个扩展了QueryDslRepositorySupport
的自定义存储库来实现这一点,以便检查权限的查询部分被自动追加并隐藏在自定义存储库实现中?
1条答案
按热度按时间s4chpxco1#
基于 这个 approach , 我 开发 了 一 个 可能 性 , 它 与其 说 是 一 个 解决 方案 , 不如 说 是 一 个 肮脏 的 变通 方案 。
方法 是 向 现有 predicate 添加 一 个 额外 的 权限 过滤 器 , 例如 那些 由 web 支持 生成 的 predicate 。 为此 , ACL 表 必须 首先 Map 为
@Immutable
JPA 实体 , 以便 QueryDsl 可以 生成 相应 的 Q 类 。应 附加 ACL 权限 筛选 器 的 此类 predicate 标有 以下 注解 。
中 的 每 一 个
此 注解 主要 保存 有关 域 类型 的 元 信息 , 这些 信息 是 构建 筛选 器 查询 所 需 的 。
格式
使用 以下 类 和 Spring 的 AOP 模块 生成 并 追加 实际 的 过滤 器 查询 。
格式
在 我 的 GitHub Gist 中 可以 找到 一 种 基于 JPA 的
Specification<T>
和 自 定义 仓库 实现 的 更 通用 的 方法 。