Spring Data Rest:基于安全性的投影

Ple*_*chi 19 spring-security jackson spring-data-jpa spring-data-rest

我正在使用当前版本的Spring Data RestSpring Data JPA并具有以下实体:

public class User {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String password;
    private String email;
   ...getter/setter methods...
}
Run Code Online (Sandbox Code Playgroud)

我也在用Spring Security.

我的用户存储库:

   @RepositoryRestResource(
     collectionResourceRel = "user", 
     path = "user", 
    excerptProjection = UserSimpleProjection.class)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {

}
Run Code Online (Sandbox Code Playgroud)

例如:

  • 用户1已登录
  • 用户1请求http://localhost:8080/user/1- 所有字段都可见
  • 用户1个请求http://localhost:8080/user/2-只是idname可见.

我和杰克逊尝试了不同的解决方案,没有一个能解决我的问题:

  • 使用JsonView:我发现没办法,ObjectMapper根据登录用户更改视图
  • 所描述的实现不同杰克逊过滤器在这里用,我发现没有办法改变的同一个问题ObjectMapper的不同的要求配置.

然后我找到了预测.

我创建了一个投影:

@Projection(name = "simple", types = User.class)
public interface UserSimpleProjection {

    public Long getId();

    public String getName();
}
Run Code Online (Sandbox Code Playgroud)

另一个详细的:

@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{

    public String getEmail();
}
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,根据我的要求,我会得到不同的结果.

有没有办法根据Spring Security自动切换投影和/或限制不同角色的不同投影?

aux*_*aux 18

您可以在投影中添加"虚拟"值属性,以通过安全检查调用服务方法:

@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{

    @Value("#{@userService.checkAccess(target)? target.email : null}")
    public String getEmail();
}
Run Code Online (Sandbox Code Playgroud)

当您的自定义UserService组件将返回true如果电子邮件予以曝光或只是有@PreAuthorizecheckAccess(..)抛出AccessDeniedException什么是对你更好.

注意,targetSpEL中的属性包含原始对象 - 由Spring-DATA提供.

  • 因为`principal`不是此上下文中使用的SpEL根对象的属性.要访问bean,可以使用`@`前缀.请阅读有关SpEL的更多信息:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html (3认同)