You want to look at @PostFilter
and @PreFilter
. They work pretty much like @PreAuthorize
, but can remove results from lists. You also want to assign different roles to your users, assuming you are not doing that already.
Global rules, like admin being able to see everything, you can implement by writing a concrete implementation of PermissionEvaluator
. You then add that to the MethodSecurityExpressionHandler
Time for a simple example.
This code was written in a text editor. It may not compile and is only here to show the steps needed
A very simplistic PermissionEvaluator
public class MyPermissionEvaluator implements PermissionEvaluator {
private static final SimpleGrantedAuthority AUTHORITY_ADMIN = new SimpleGrantedAuthority('admin');
public boolean hasPermission(final Authentication authentication, final Object classId, final Object permission) {
boolean permissionGranted = false;
// admin can do anything
if (authentication.getAuthorities().contains(AUTHORITY_ADMIN)) {
permissionGranted = true;
} else {
// Check if the logged in user is in the same class
}
return permissionGranted;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return false;
}
}
Then configure method security
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Bean
public MethodSecurityExpressionHandler methodSecurityExpressionHandler(final PermissionEvaluator permissionEvaluator){
DefaultMethodSecurityExpressionHandler securityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
securityExpressionHandler.setPermissionEvaluator(permissionEvaluator);
return securityExpressionHandler;
}
@Bean
public PermissionEvaluator permissionEvaluator() {
return new MyPermissionEvaluator();
}
}
Now we can use our filter on a method
@PostFilter("hasPermission(filterObject.getClassId(), 'READ')")
@Override
public List<Student> getAll() {
return querySomeStudents();
}
hasPermission
in the @PostFilter
ACL will invoke hasPermission
in MyPermissionEvaluator
. filterObject
refers to the individual items in the list. Wherever you code returns false, it will remove the item from the list.