yng*_*gwi 6 spring-security spring-data-neo4j spring-data-rest
我正在尝试使用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;
}
Run Code Online (Sandbox Code Playgroud)
@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;
}
Run Code Online (Sandbox Code Playgroud)
@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;
}
Run Code Online (Sandbox Code Playgroud)
我现在试图让所有内容尽可能简单,因此我只使用存储库扩展GraphRepository和使用基本身份验证和User对象/存储库的Spring Security配置UserDetailsService.这是按预期工作的,我能够创建用户,创建一些对象等等.
问题是,我希望用户只能访问自己的实体.目前,每个人都可以访问所有内容.正如我从研究中所理解的那样,我有三种方法可以实现这一点:
@PostAuthorize("returnObject.user.username == principal.username")
@Override
Activity findOne(Long id);
Run Code Online (Sandbox Code Playgroud)
@PostFilter("filterObject.user.username == principal.username")
@Override
Iterable<Activity> findAll();
Run Code Online (Sandbox Code Playgroud)
@Query使用自定义查询注释方法并获取数据.现在我的问题:
使用我的可用工具实现所需功能的最佳方法是什么?
对我来说,它似乎是使用#2(自定义查询)的首选方式.这样我只能获取实际需要的数据.我将不得不尝试找到一种方法来创建一个支持分页的查询,Page<Activity> findAll(Pageable pageable)但我希望这是可能的.我虽然无法principal.username在自定义查询中使用.似乎spring-data-neo4j 现在不支持SpEL.这是正确的还是有另一种方法来访问查询中当前经过身份验证的用户?
方式#1,使用Spring Security Annotations对我有用(参见上面的代码),但我无法弄清楚如何过滤,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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2398 次 |
| 最近记录: |