如果我有如下所示的存储库设置,使用Spring Data REST,我可以访问/ receipt上的数据并查看所有数据。但是,我只想为用户返回数据。我有一个自定义查找程序“findByStorer”,它会这样做。我如何让Spring Data REST使用它并从用户那里获取storer值而不是指定查询参数?
@RepositoryRestResource(collectionResourceRel = "receipts", path = "receipts")
public interface ReceiptRepository extends PagingAndSortingRepository<Receipt, BigDecimal> {
@Query
public Page<Receipt> findByStorer(String storer, Pageable pageable);
}
我还没有实施任何安全措施,所以这个问题目前比实践更具理论性。
感谢。
答案 0 :(得分:3)
基于@ rpr的回答:
您应该能够引用已连接实体(Storer)的属性。在您的示例中,如果您有收据 - &gt; Storer - &gt;用户可以查询收据,其中Storer.user具有从安全上下文中注入的值。
@PreAuthorize("isFullyAuthenticated && (#userName==principal.username)")
Page<Receipt> findByStorer_User(@Param("userName") String userName)
答案 1 :(得分:2)
如果您使用Spring Security,则可以使用此方法:
@PreAuthorize("isFullyAuthenticated() && (#userName == principal.username)")
public List<User> findByUserName(@Param("userName")String userName);
答案 2 :(得分:2)
例如,给定Repository
SomeEntity
,您可以使用属性findAll
的自定义@Query
覆盖来覆盖owner
方法,其值为`#{ 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();
}
答案 3 :(得分:0)
这个问题是一个典型的交叉问题,所以我尝试应用AOP。定义建议并更新args(String storer),如下所示: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);
}
}