如何通过角色限制对Spring Data REST投影的访问?

时间:2015-11-11 23:29:53

标签: java spring rest spring-data spring-data-rest

在使用Spring Data JPA和Spring Data REST的应用程序中,让我们假设你有一个这样的实体类:

@Entity
public class Person {

   @Id @GeneratedValue
   private int id;

   private String name;

   @JsonIgnore
   private String superSecretValue;

   ...

}

我们希望Spring Data REST公开superSecretValue以外的所有实体的字段,因此我们使用@JsonIgnore注释该字段。

但是,在某些情况下,我们要访问superSecretValue,因此我们创建了一个投影,它将返回包含该字段的所有字段:

@Projection(name = "withSecret", types = {Person.class})
public interface PersonWithSecret {

   String getName();
   String getSuperSecretValue();

}

真棒。现在我们可以像这样访问Person个实体,包括 superSecretValue字段:

curl http://localhost:8080/persons?projection=withSecret

我的问题是我们如何确保投影 ?我们如何配置以下内容:任何人都可以在没有 Person字段的情况下检索superSecretValue个实体 ...但只有具有特定角色的人(例如ROLE_ADMIN)可以使用投影来检索隐藏的字段吗?

我找到了无数使用@PreAuthorize@Secured注释来保护Spring Data JPA存储库CRUD方法的示例(例如save()delete())...但没有关于如何限制使用Spring Data REST投影的示例。

2 个答案:

答案 0 :(得分:2)

您可以使用带有条件SpEL表达式的@Value重叠投影中的属性 - 如此already answered similar question

考虑其他替代方案(其他已经提到的):

  1. 模型重构。按访问逻辑拆分实体(例如Person< - > Account
  2. 为特殊逻辑和访问检查添加自定义端点。例如,当前用户位于“/ people / me”。
  3. 自定义标准端点。例如,为“/ people”,“/ people / {id}”添加自定义控制器,它将预处理并返回自定义Resource类型(DTO),具体取决于用户权限(例如,返回PublicPerson而不是Person {1}})。然后,您可以编写自定义资源处理器,以便为这些类型添加自定义链接和自定义投影。
  4. 另请参阅:spring-data-rest DATAREST-428中有关此主题的问题。

答案 1 :(得分:0)

您可以尝试此解决方案:https://stackoverflow.com/a/35399030/679240

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

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