If I have a repository setup like the following, making use of Spring Data REST, I can access the data at /receipts and see all data. However, I want to only return data fo
Building on @rpr's answer:
You should be able to reference properties of the joined entity (Storer). In your example if you have Receipt -> Storer -> User you can query the Receipts where Storer.user has a value injected from the Security Context.
@PreAuthorize("isFullyAuthenticated && (#userName==principal.username)")
Page<Receipt> findByStorer_User(@Param("userName") String userName)
This issue is a tipical cross-cutting concern so I tried apply AOP. Define Advice and update the args (String storer), as explain at: https://stackoverflow.com/a/46353783/1203628
@Aspect
@Transactional
@Component
public class FilterProjectsAspect {
@Pointcut("execution(* com.xxx.ReceiptRepository.findByStorer(..))")
public void projectFindAll() {
}
@Around("projectFindAll()")
public Object filterProjectsByUser(final ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof String) {
String storer=(String) args[i];
// Find storer by user
args[i]=storer; //Update args
}
return pjp.proceed(args);
}
}
If you use Spring Security you can use this approach:
@PreAuthorize("isFullyAuthenticated() && (#userName == principal.username)")
public List<User> findByUserName(@Param("userName")String userName);
For example, given a Repository
for SomeEntity
you could override findAll
method with a custom @Query
filtering by attribute owner
with value of`#{principal.username}
@RepositoryRestResource(path = "some-entities", collectionResourceRel = "some-entities", itemResourceRel = "some-entity")
interface SomeEntityRepository extends PagingAndSortingRepository<SomeEntity, String> {
@Override
@RestResource(exported = true)
@Query("select someEntity from SomeEntity someEntity where someEntity.owner = ?#{principal.username}")
Iterable<SomeResource> findAll();
}