Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 636
Zack Avatar asked Feb 21 '15 16:02

Zack


People also ask

How does authentication work in Spring Security?

There are multiple filters in spring security out of which one is the Authentication Filter, which initiates the process of authentication. Once the request passes through the authentication filter, the credentials of the user are stored in the Authentication object.

Which mechanism is used by Spring Security?

Remember Me authentication is the mechanism to recognize the user after their session times out, so the users do not need to enter their credentials every time they visit the website. Spring Security supports multiple ways to implement this type of authentication.

How does Spring Security works in spring boot?

Spring-security requires you to create a service which implements UserDetailsService. It expects service to have loadUserByUsername method which returns user object (which needs to implement Spring's User class). This instance of user is used to get authorities so that you can restrict access to certain urls.

What Spring Security annotation can you use to filter the results of a method?

Simply put, the @PreFilter and @PostFilter annotations are used to filter lists of objects based on custom security rules we define. @PostFilter defines a rule for filtering the return list of a method, by applying that rule to every element in the list.


2 Answers

@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.

like image 165
vtor Avatar answered Sep 28 '22 01:09

vtor


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.

like image 44
Wecherowski Avatar answered Sep 28 '22 03:09

Wecherowski