在 Spring 数据 JPA 查询中注入用户
Injecting user on Spring Data JPA queries
我主要使用 JPA 和 Hibernate,但我对 Spring Data JPA 比较陌生。我正在尝试注入已登录的用户,以便查询对用户的可见性进行限制。
假设我们有这个实体:
public class Group {
private String code;
private String name;
private String creationUserId;
}
而 CreationUserId 是实体用户的列 Id 的 FK。这试图表示只有 ID 等于此 creationUserId 的用户才能访问此组。
所以,考虑到我使用的是 JWT(令牌上的主题是用户 ID)和 springSecurity(因此用户在 SecurityContextHolder.getContext().getAuthentication()
中),是否有任何奇特的方式来做类似
public List<Groups> findMyGroups () {
return groupsRepository.findMyGroups();
}
使用 SpringDataJPA 给我们的功能?
我尽量避免做类似
的事情
public List<Groups> findMyGroups () {
MyUser u = (MyUser)SecurityContextHolder.getContext().getAuthentication().getDetails();
return groupsRepository.findGroupsByUserCreationId(u.getId());
}
我这样做没有问题,但它会导致这样的样板文件,也许有一些解决方法可以实现它。
当然我不希望在每个查询中都使用这个,只是在某些查询中(有两种不同的安全角色用于列表,group:readAll 和 group:readMine)。
Spring 安全性提供与 Spring 数据的集成以实现您想要的。看看 reference documentation about that.
简而言之,您必须添加依赖项并公开一个 SecurityEvaluationContextExtension
类型的 Bean,如下所示:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
有了这个后,您可以在查询中使用 Authentication
:
@Query("SELECT g FROM Group g WHERE g.creationUserId = ?#{principal?.id}")
List<Group> readMine();
我主要使用 JPA 和 Hibernate,但我对 Spring Data JPA 比较陌生。我正在尝试注入已登录的用户,以便查询对用户的可见性进行限制。
假设我们有这个实体:
public class Group {
private String code;
private String name;
private String creationUserId;
}
而 CreationUserId 是实体用户的列 Id 的 FK。这试图表示只有 ID 等于此 creationUserId 的用户才能访问此组。
所以,考虑到我使用的是 JWT(令牌上的主题是用户 ID)和 springSecurity(因此用户在 SecurityContextHolder.getContext().getAuthentication()
中),是否有任何奇特的方式来做类似
public List<Groups> findMyGroups () {
return groupsRepository.findMyGroups();
}
使用 SpringDataJPA 给我们的功能?
我尽量避免做类似
的事情public List<Groups> findMyGroups () {
MyUser u = (MyUser)SecurityContextHolder.getContext().getAuthentication().getDetails();
return groupsRepository.findGroupsByUserCreationId(u.getId());
}
我这样做没有问题,但它会导致这样的样板文件,也许有一些解决方法可以实现它。
当然我不希望在每个查询中都使用这个,只是在某些查询中(有两种不同的安全角色用于列表,group:readAll 和 group:readMine)。
Spring 安全性提供与 Spring 数据的集成以实现您想要的。看看 reference documentation about that.
简而言之,您必须添加依赖项并公开一个 SecurityEvaluationContextExtension
类型的 Bean,如下所示:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
有了这个后,您可以在查询中使用 Authentication
:
@Query("SELECT g FROM Group g WHERE g.creationUserId = ?#{principal?.id}")
List<Group> readMine();