2014-05-13 29 views
8

如果我有一個類似以下的存儲庫設置,利用Spring Data REST,我可以訪問/ receipts處的數據並查看所有數據。但是,我只想爲用戶返回數據。我有一個自定義發現者「findByStorer」,這將做到這一點。我將如何獲得Spring Data REST來使用它並從用戶獲取storer值而不是指定查詢參數?Spring Data REST過濾基於用戶的數據

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

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

我還沒有實現任何安全性,所以這個問題現在比實踐更理論。

謝謝。

回答

2

如果你使用Spring Security,你可以使用這種方法:

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

這並不完全解釋如何從用戶名到該貯藏器,例如,如果加入回執表,用戶表你需要通過Storer表。 IE,類似'select * from user,receipt where user.storer = receipt.storer'。 – JBCP

3

大廈@ RPR的回答是:

您應該能夠引用加盟實體(斯托勒)的性能。在您的示例中,如果您有Receipt - > Storer - > User,則可以查詢Recerts,其中Storer.user具有從安全上下文注入的值。

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

我們如何才能使findByStorer_User()方法成爲默認值,當具有有限訪問權限的用戶使用API​​時,替換findAll()?我們希望爲管理員用戶保留findAll(),併爲限制用戶提供有限的方法。 – Wouter

1

例如,給定一個RepositorySomeEntity你可以通過屬性owner與值覆蓋findAll方法與自定義過濾@Query#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(); 
} 
0

這個問題是一個tipical所以我嘗試應用AOP。定義建議和更新ARGS(字符串貯藏器),如在講解: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); 
    } 

}