Spring-security: SEC-3212: Unable to use @PostFilter with Spring Data paging

Created on 4 Feb 2016  路  10Comments  路  Source: spring-projects/spring-security

Chen Li (Migrated from SEC-3212) said:

I was trying to authorize apis work with Spring Data JPA. When I try to authorize permission for getting page of entities, it throws the exception: java.lang.IllegalArgumentException: Filter target must be a collection or array type, but was Page 0 of 3 containing domain.Consumption instances

The code is:

@PreAuthorize(
        "hasRole('ROLE_USER')")
@PostFilter(
        "hasPermission(filterObject, 'read') or " +
        "hasPermission(filterObject, admin)")
Page<Consumption> getAllConsumptions(Pageable pageable);

Will Spring Security filter those are not a collection nor array like 'org.springframework.data.domain.Page' above?

declined enhancement jira

All 10 comments

Rob Winch said:

Thanks for the report! It is unlikely Spring Security will ever support @PostFilter on Page objects. This is because the result won't be valid anymore (i.e. you request 10 results, Spring Security will remove 2 of them and you will only have 8). Instead, you should use the Spring Data integration to update your query. See http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#data

Chen Li said:

@Rob You are right. Thank you :)

@rwinch
I am having trouble replacing the @PostFilter with @Query and hasPermission.
Is there an example for this type of query ?
Something along the lines of
@Query("select e from MyEntity e where 1= ?#{hasPermission(e.id,'com.foo.MyEntity', 'read') } ") Page<MyEntity> findEntities(Pageable pageable);

@rwong2000 Did you ever get an example for this? I'm trying to do the same thing

@jorgeliano-lcg & @rwong2000 did you guys find any solution to ?

@Query("select e from MyEntity e where 1= ?#{hasPermission(e.id,'com.foo.MyEntity', 'read') } ") Page<MyEntity> findEntities(Pageable pageable);

Maybe not the right place, but how you manage such a query on a no sql db like mongo?
Actually we got:
@Query("{organization: ?#{ hasRole('ROLE_MANAGER') ? {$exists:true} : principal.organizationId}}") Page<Briefing> findAll(Pageable pageable);
So if the user has the role manager he will get all entities otherwise only the one of his organization. I prefer using hasPermission instead of hasRole. Any idea?

Refering to:

Rob Winch said:

Thanks for the report! It is unlikely Spring Security will ever support @PostFilter on Page objects. This is because the result won't be valid anymore (i.e. you request 10 results, Spring Security will remove 2 of them and you will only have 8). Instead, you should use the Spring Data integration to update your query. See http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#data

With the following code:

public interface BookRepository extends JpaRepository<Book, Long> {
    @PreAuthorize("hasAuthority('AUTHOR')")
    @Query("select b from Book b where b.author.id = ?#{ principal?.id }")
    Page<Facility> findAllOwned(Pageable p);
}

I'm getting the below error:

org.springframework.expression.spel.SpelEvaluationException: 
EL1008E: 
Property or field 'id' cannot be found on object of type 'java.lang.String' - maybe not public?

The full issue is in Stackoverflow https://stackoverflow.com/questions/48478982/spelevaluationexception-when-using-spring-security-expressions-with-query

I'm also working with Spring Data and Spring Security ACL and I have the same problem as @rwong2000 , @jorgeliano-lcg and @saubhagyab .
Is there any working solution for that, I did not find anything on stackoverflow or elsewhere.
I have debugged it and it searches with e.id on Page or Pageable instead of MyEntity.

Same as @rwong2000, trying to access to a SPQL parameter in a SpEL expression that is itself in the SPQL.

@Query("select o from #{#entityName} o where 1 = ?#{@someBean.some(o, authentication)} ") Page<T> findAll(Pageable pageable);

But can't figure how to access 'o' in SpEL.

Has anybody have any solution for this ? else any workaround for applying security over Page returning repository methods ? i can do a default implementation and apply security over it , but still checking is there any solution for this.

Was this page helpful?
0 / 5 - 0 ratings