放松Spring Data REST投影的安全性

时间:2015-02-18 08:59:19

标签: spring spring-security spring-data spring-data-rest

我有一个User类,我想授权访问,只有用户才能看到他有权使用的内容。

使用Spring Security和Spring Data Rest可以很容易地实现这一点,我在下面的JPA Repository中做了这些 -

public interface UserRepository extends JPARepository<User,Integer> {

    @PreAuthorize("hasRole('LOGGED_IN') and principal.user.id == #id")
    User findOne(@Param("id") Integer id);

}

通过这种方式,用户访问Spring Data REST时可以使用支持URL,例如 -

/users/{id}
/users/{id}/userPosts

只有使用{id}登录的用户才能看到这些内容,而其他所有人都可以获得401,就像我想要的那样。

我的问题是我有一个预测,它是每个用户的公开视图,我正在使用下面的Spring Data Rest投影来创建它,我希望每个{id}

都可以访问
@Projection(name = "details", types = User.class)
public interface UserDetailsProjection {
..
}

因此,即使用户已通过 /users/{id1}?projection=details

登录,/users/{id2}?projection=details以及{id1}仍应提供200 OK并显示数据

我开始通过使用@PreAuthorize(&#34; permitAll&#34;)标记投影来实现这一点,但由于存储库具有更难的安全检查,因此无法工作。我们是否可以使用此功能进行投影,我们可以放松安全性?

我正在使用最新的Spring Data Rest和Spring Security发行版

2 个答案:

答案 0 :(得分:2)

为这个用例添加自定义控制器似乎是合理的。

还请考虑:

  • 使用@Value注释
  • 评估投影中的访问权限
  • 为同一数据库数据添加另一个实体,但为只读操作设置了不同的字段,例如使用继承(小心缓存等) - 取决于您的数据存储类型
  • 修改模型以将User实体拆分为两个不同的实体(配置文件,帐户),因为它们似乎具有不同的访问权限,甚至可能是操作
  • 您还可以添加ResourceProcessor<UserSummaryProjection>以编程方式评估访问权限并使用DTO替换资源内容(投影)

使用@Value注释评估投影中的访问权限的示例:

@Projection(types = User.class, name = "summary")
public interface UserSummaryProjection {
  @Value("#{@userSecurity.canReadEmail(target) ? target.email: null}")
  String getEmail();
}

答案 1 :(得分:0)

在数据访问层中添加Spring安全代码不是一个好主意。我建议你将@PreAuthorize注释添加到控制器/服务方法中。由于您有一个查询参数?projection=details,因此您可以使用单独的控制器/服务方法进行详细信息投影。

在您的详细信息投影方法中添加以下内容:

@RequestMapping("/url", params = {"projection"})
@PreAuthorize("hasRole('LOGGED_IN') and principal.user.id == #id")