복붙노트

[SPRING] 스프링 데이터 REST 사용자에 따라 데이터 필터링

SPRING

스프링 데이터 REST 사용자에 따라 데이터 필터링

다음과 같은 저장소 설정이있는 경우 Spring Data REST를 사용하여 / receipts의 데이터에 액세스하고 모든 데이터를 볼 수 있습니다. 그러나 사용자의 데이터 만 반환하려고합니다. 나는 이것을 할 사용자 정의 파인더 "findByStorer"를 가지고있다. 어떻게하면 Spring 데이터 REST를 사용하여 쿼리 매개 변수를 지정하는 대신 사용자로부터 storer 값을 얻을 수 있습니까?

@RepositoryRestResource(collectionResourceRel = "receipts", path = "receipts")
public interface ReceiptRepository extends PagingAndSortingRepository<Receipt, BigDecimal> {

    @Query
    public Page<Receipt> findByStorer(String storer, Pageable pageable);
}

아직 보안을 구현하지 않았기 때문에이 질문은 실전보다 더 많은 이론입니다.

감사.

해결법

  1. ==============================

    1.@ rpr의 답변 작성 :

    @ rpr의 답변 작성 :

    조인 된 엔터티 (Storer)의 속성을 참조 할 수 있어야합니다. Receipt -> Storer -> User가있는 경우 Storer.user에 보안 컨텍스트에서 주입 된 값이있는 수령을 조회 할 수 있습니다.

    @PreAuthorize("isFullyAuthenticated && (#userName==principal.username)")
    Page<Receipt> findByStorer_User(@Param("userName") String userName)
    
  2. ==============================

    2.Spring Security를 ​​사용한다면이 접근법을 사용할 수 있습니다 :

    Spring Security를 ​​사용한다면이 접근법을 사용할 수 있습니다 :

    @PreAuthorize("isFullyAuthenticated() && (#userName == principal.username)")
    public List<User> findByUserName(@Param("userName")String userName);
    
  3. ==============================

    3.예를 들어, SomeEntity에 대한 Repository를 지정하면 속성 소유자 인`# {principal.username} '에 의한 맞춤 @Query 필터링으로 findAll 메소드를 재정의 할 수 있습니다.

    예를 들어, SomeEntity에 대한 Repository를 지정하면 속성 소유자 인`# {principal.username} '에 의한 맞춤 @Query 필터링으로 findAll 메소드를 재정의 할 수 있습니다.

    @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();
    }
    
  4. ==============================

    4.이 문제는 크로스 커팅의 근본적인 문제이므로 AOP 적용을 시도했습니다. Advice를 정의하고 args (String storer)를 업데이트하십시오 (https://stackoverflow.com/a/46353783/1203628).

    이 문제는 크로스 커팅의 근본적인 문제이므로 AOP 적용을 시도했습니다. Advice를 정의하고 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);
        }
    
    }
    
  5. from https://stackoverflow.com/questions/23640487/spring-data-rest-filtering-data-based-on-the-user by cc-by-sa and MIT license