I\'m attempting to implement fine grain access control while still taking advantage of Spring data rest.
I\'m working on securing a CrudRepository
so u
As of Spring Security 4.0 you can access security context in Spring Data JPA queries.
Add SecurityEvaluationContextExtension
bean to your bean context:
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
Now you should be able to access Principal
in your Spring Data queries:
@Query("select count(m) from MyObject as m where m.user.id = ?#{ principal?.id }")
@Override
long count();
@Modifying
@Query("delete from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
@Override
void delete(Integer integer);
@Modifying
@Query("delete from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
@Override
void delete(MyObject entity);
@Modifying
@Query("delete from MyObject as m where m.user.id = ?#{ principal?.id }")
@Override
void deleteAll();
@Query("select 1 from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
@Override
boolean exists(Integer integer);
Caution. Queries might have errors. I hadn't the time to test it.
Can also be achieved by implementing your checks in your custom Spring repository event handlers. See @HandleBeforeCreate
, @HandleBeforeUpdate
, @HandleBeforeDelete
.
Alternatively, you can use permission-based expressions, e.g. with ACL or your custom ones, you can write @PreAuthorize("hasPermission(#id, 'MyObject', 'DELETE')")
.