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

20

我正在使用当前版本的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...
}

我也在使用Spring Security

我的用户仓库:

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

}

例如:

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

我尝试使用Jackson的不同解决方案,但没有一个能解决我的问题:

  • 使用JsonView: 我发现没有办法根据登录的用户更改ObjectMapper的视图
  • 按照此处所述实施了不同的Jackson过滤器,但仍然无法为不同的请求更改ObjectMapper的配置。

然后我发现了投影

我创建了一个投影:

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

    public Long getId();

    public String getName();
}

还有另一个详细的:

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

    public String getEmail();
}

目前为止还不错,我得到了不同的结果,这取决于我的请求。

是否有一种方法可以根据Spring Security自动切换投影并/或限制不同角色的不同投影?


你有没有偶然间成功实现基于角色的投影? - ArunM
不好意思,我当时放弃了并制作了自定义控制器。 - Plechi
3个回答

20

您可以将一个“虚拟”的值属性添加到投影中,该属性调用带有安全检查的服务方法:

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

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

如果你的自定义UserService组件应该公开电子邮件地址,或者仅仅在checkAccess(..)上使用@PreAuthorize抛出AccessDeniedException,取决于你的实际需求。

请注意,在SpEL中,target属性保存了由Spring-DATA提供的原始对象。


为什么这个不起作用 @Value("#{principal.username.equalsIgnoreCase('admin') ? target.password : null}") - ArslanAnjum
3
因为在这个上下文中,principal不是SpEL根对象的属性。要访问bean,您可以使用@前缀。请阅读有关SpEL的更多信息:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html - aux
注意,在SPeL中,您可以使用变量(#myvar),Bean(@mybean),“根对象”属性和方法等。还要注意,在不同的上下文中,表达式具有不同的“根对象”,由一些处理程序设置。例如,@PreAuthorizeMethodSecurityExpressionHandler 处理,投影 @ValueSpelAwareProxyProjectionFactory 处理。您可以查看源代码以供参考。 - aux

2

您也可以在Spring Security配置中使用RegexRequestMatcher来完成此操作:

.regexMatchers(HttpMethod.GET,"/user/.*projection=simple.*").hasRole("ROLE_ADMIN")

0
不,Spring Data REST的投影不支持此功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接