Spring Data Rest:基于安全的投影

Posted

技术标签:

【中文标题】Spring Data Rest:基于安全的投影【英文标题】:Spring Data Rest: Security based projection 【发布时间】:2015-05-01 21:09:07 【问题描述】:

我正在使用当前版本的Spring Data Rest 和Spring 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 的视图 按照here 的描述实现了不同的 Jackson 过滤器,但我发现无法针对不同的请求更改 ObjectMapper 配置。

然后我找到了Projections。

我创建了一个投影:

@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 自动切换投影和/或限制不同角色的不同投影?

【问题讨论】:

您是否有机会根据角色进行预测? 不,对不起。我当时放弃并制作了自定义控制器。 【参考方案1】:

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

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

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

如果电子邮件应该被公开,或者只是在checkAccess(..) 上有@PreAuthorize 以抛出一个AccessDeniedException 任何对你更好的东西,你的自定义UserService 组件将返回true

注意,SpEL 中的target 属性包含原始对象 - 由 Spring-DATA 提供。

【讨论】:

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

您也可以在 Spring Security 配置中使用 RegexRequestMatcher,如下所示:

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

【讨论】:

【参考方案3】:

不,Spring Data REST 预测不支持这一点。

【讨论】:

以上是关于Spring Data Rest:基于安全的投影的主要内容,如果未能解决你的问题,请参考以下文章

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

在 Spring Data rest json Response 中动态过滤实体字段

Spring Data Rest 中的字段安全性

关于基于 Spring 安全 URL 的安全性的说明 [重复]

Spring boot:无法从另一个 Origin 访问安全资源 - CORS - Spring Security - Spring data rest

苹果电脑连接电视投影的东西叫啥