Let's assume the following Spring JPA based repository with QueryDsl support.
@Repository
public interface TeamRepository extends JpaRepository<Team, Long>, QuerydslPredicateExecutor<Team> {
}
The application uses Access Control Lists (ACL) in service layer for checking permission for individual resources using @PreAuthorize(hasPermission(#id, 'Team', 'READ') for example.
I want to allow a user to request all teams for which he has read permission. I tried to use
@PostFilter(hasPermission(filterObject, 'READ'), that works pretty good as long as I use Iterable<Team> findAll(Predicate predicate). But when I try to make use of pagination, @PostFilter seems to throw an exception.
java.lang.IllegalArgumentException: Filter target must be a collection, array, or stream type, but was Page 1 of 0 containing UNKNOWN instances
The official Spring Security Reference Documentation recommends to write a custom query using @Query which supports pagination.
How could I write such a complex query which supports QueryDsl's Predicate, Pagination and filtering based on permissions?
Approach 03/24/20
In another forum I came across the following QueryDsl based approach: Instead of a native or custom query, the ACL tables are mapped as @Immutable JPA entities, thus generating Q classes and using them to filter for permissions manually.
@Entity
@Immutable
@Table(name = "acl_object_identity")
public class AclObjectIdentity implements Serializable {
...
}
How could you do this using a custom repository, extending QueryDslRepositorySupport, so that the part of the query that checks permissions is automatically appended and hidden inside of a custom repository implementation?