How do @PostFilter and @PreFilter work in Spring Security?

15,896

Solution 1

@PreFilter and @PostFilter are designated to use with Spring security to be able to filter collections or arrays based on the authorization.

To have this working, you need to use expression-based access control in spring security (as you have in your example)

@PreFilter - filters the collection or arrays before executing method.

@PostFilter - filters the returned collection or arrays after executing the method.

So, let's say your getUser() returns List of Users. Spring Security will iterate through the list and remove any elements for which the applied expression is false (e.g. is not admin, and does not have read permission)

filterObject is built-in object on which filter operation is performed and you can apply various conditions to this object (basically all built-in expressions are available here, e.g. principal, authentication), for example you can do

@PostFilter ("filterObject.owner == authentication.name")

Though those filters are useful, it is really inefficient with large data sets, and basically you lose control over your result, instead Spring controls the result.

Solution 2

Since the currently accepted answer didn't go into @PreFilter, here's my two cents:

(Quote from the JavaDocs)

Annotation for specifying a method filtering expression which will be evaluated before a method has been invoked. The name of the argument to be filtered is specified using the filterTarget attribute. This must be a Java Collection implementation which supports the remove method.

@PreFilter operates on the method arguments, not the return value. If the annotated method only has a single Collection argument, then the filterTarget annotation argument can be omitted.

Share:
15,896
Zack
Author by

Zack

Updated on June 21, 2022

Comments

  • Zack
    Zack almost 2 years

    Being new to Spring's security annotations, I need a clarification for the below code.

    @PostFilter("hasPermission(filterObject, 'READ') or hasRole('ROLE_ADMIN')")
    public List<User> getUsers(String orderByInsertionDate,
                Integer numberDaysToLookBack) throws AppException
    

    So this means that the list of users returned by getUsers will only contain those elements which have full "READ" access to the calling object or the calling object has role as "ROLE_ADMIN". Thanks.

  • Sim0rn
    Sim0rn over 5 years
    Great description. Helped me with filtering my Resulst. Thank you
  • Saurabh Tiwari
    Saurabh Tiwari about 4 years
    PostFilter is pretty much self-explanatory in the sense that Spring filters the result after they have been fetched from the datasource. Can you explain how @Prefilter filters even before fetching the data.
  • Wecherowski
    Wecherowski almost 4 years
    @SaurabhTiwari, see my answer