我正在尝试使用带有Spring Data Neo4j,Spring Data Rest和Spring Security的Spring Boot(版本1.4.0.M2)创建REST API 。域由三种类型的实体组成:
@NodeEntity
public class User extends Entity {
@Relationship(type = "OWNS")
private Set<Activity> activities;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
private String username;
}
@NodeEntity
public class Activity extends Entity {
private String name;
@Relationship(type = "ON", direction = Relationship.INCOMING)
private Set<Period> periods;
@Relationship(type = "HAS", direction = Relationship.INCOMING)
private User user;
}
@NodeEntity
public class Period extends Entity {
@Relationship(type = "HAS")
private Set<Activity> activities;
@Relationship(type = "HAS_PERIOD", direction = Relationship.INCOMING)
private Day day;
private PeriodNames name;
}
我现在试图使所有事情都尽可能简单,因此我只使用Repository扩展GraphRepository
和Spring Security配置,该配置使用Basic Authentication和中的User
Object / Repository UserDetailsService
。这按预期工作,我能够创建用户,创建一些对象等。
问题是,我只希望用户访问自己的实体。目前,每个人都可以访问所有内容。从我的研究中了解到,我可以通过三种方式实现这一目标:
@PostAuthorize("returnObject.user.username == principal.username")
@Override
Activity findOne(Long id);
@PostFilter("filterObject.user.username == principal.username")
@Override
Iterable<Activity> findAll();
@Query
并使用自定义查询来获取数据。现在我的问题是:
使用我的可用工具来实现所需功能的最佳方法是什么?
对我来说,这似乎是使用#2(自定义查询)的首选方式。这样,我只能获取我实际需要的数据。我将不得不尝试找到一种方法来创建启用分页的查询,Page<Activity> findAll(Pageable pageable)
但是我希望这是可能的。我无法principal.username
在自定义查询中使用。似乎spring-data-neo4j目前不支持SpEL。这是正确的还是在查询中还有另一种访问当前经过身份验证的用户的方法?
使用Spring Security Annotations的方式1对我有效(请参见上面的代码),但是我无法弄清楚如何过滤,Page<Activity> findAll(Pageable pageable)
因为它返回的是Page
对象而不是实体或集合。另外,我不确定这种方式是否有效,因为数据库始终必须查询所有实体,而不仅是查询特定用户拥有的实体。这似乎是对资源的浪费。这不正确吗?
还是我应该只使用#3并实现自定义控制器和服务?还有我没有读过的另一种方式吗?
非常感谢您提供有关此主题的任何意见!
谢谢,丹尼尔
好的,我想我已经找到了解决方案。我猜它不是很漂亮,但目前可以使用。我对用于@PostAuthorize("returnObject.user.username == principal.username")
单个实体的存储库方法使用或类似的方法,并为此创建了一个默认实现,Page<Activity> findAll(Pageable pageable)
该实现仅通过调用来获取用户名,SecurityContextHolder.getContext().getAuthentication().getName()
并调用一个获取正确数据的自定义查询方法:
@RestResource(exported = false)
@Query("MATCH (u:User)-[:HAS]->(a:Activity) WHERE u.username={ username } RETURN a ORDER BY CASE WHEN NOT { sortingProperty} IS NULL THEN a[{ sortingProperty }] ELSE null END SKIP { skip } LIMIT { limit }")
List<Activity> findAllForUsernamePagedAndSorted(@Param("username") String username, @Param("sortingProperty") String sortingProperty, @Param("skip") int skip, @Param("limit") int limit);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句