2

In my project I use Spring-Data, Spring-Data-Rest and Spring-Security.

What I need to accomplish is to implement domain object security (ACL) over these repositories. Specificaly @PostFilter over Pageable.findAll() method.

Method level security is easily implemented as outlined here.

There is also a section in docs about using security expression with @Query here.

But although I can use hasPermission(..) method inside @Query too, there is no way to include the object (SQL row) in this method - to be specific do this:

@Query("select u from #{#entityName} u where 1 = ?#{security.hasPermission(u, 'read') ? 1 : 0}")

Now I understand that this is way different than modifying the query pre-execution like this:

@Query("select m from Message m where m.to.id = ?#{ principal?.id }")

I also found the following jira issue: https://jira.spring.io/browse/DATACMNS-293 Which I suspect that once it gets resolved there will be a solution to this, but it doesn't seem like it's going to be anytime soon.

I still need to implement this functionality and for that I would like to get your input and pointers on possible solutions.

Right now I am thinking about creating my custom annotation that will mimmick the @PostFilter one and use the same syntax but will get invoked manually inside my own BaseRepositoryImplementation. There I will get the repository interface from type and Repositories#getRepositoryInformationFor(type)#getRepositoryInterface(), find the annotation on respective method and manually invoke the security check.

Do you maybe have a different solution, or some notes about my proposed solution?

Also do you happen to know if there is any timetable on the mentioned jira issue?

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
JIMI
  • 439
  • 2
  • 8

1 Answers1

0

One lightweight way is to do it is using the hasPermission() method and implementing your own "Permission Evaluator" at the Controller level, if that's an option for you.

@PreAuthorize("hasPermission(#employee, 'edit')")
public void editEmployee(Employee employee) {
   ...
}

@Component
public class PermissionEvaluatorImpl implements PermissionEvaluator {
    @Override
    public boolean hasPermission(Authentication auth,
            Object targetDomainObject, Object permission) {
        // return true if "auth" has "permission" permission for the user.
        // Current-user can be obtained from auth.
    }
    ...
}

This is described in more detail here: http://www.naturalprogrammer.com/spring-domain-object-security-logged-in-user/

Abi
  • 31
  • 4