在 Spring Data 存储库中包含域对象安全 @PostFilter 可分页端点

Posted

技术标签:

【中文标题】在 Spring Data 存储库中包含域对象安全 @PostFilter 可分页端点【英文标题】:Including Domain Object Security @PostFilter in Spring Data repositories Pageable endpoints 【发布时间】:2017-03-09 21:22:15 【问题描述】:

在我的项目中,我使用 Spring-Data、Spring-Data-Rest 和 Spring-Security。

我需要完成的是在这些存储库上实现域对象安全 (ACL)。特别是 @PostFilter 超过 Pageable.findAll() 方法。

如here 所述,方法级别的安全性很容易实现。

文档中还有一节关于使用@Query here 的安全表达式。

但是虽然我也可以在@Query 中使用hasPermission(..) 方法,但是没有办法在这个方法中包含对象(SQL 行)——具体来说这样做:

@Query("select u from ##entityName u where 1 = ?#security.hasPermission(u, 'read') ? 1 : 0")

现在我明白这与像这样修改查询预执行的方式不同:

@Query("select m from Message m where m.to.id = ?# principal?.id ")

我还发现了以下 jira 问题: https://jira.spring.io/browse/DATACMNS-293 我怀疑一旦它得到解决,就会有解决方案,但似乎不会很快出现。

我仍然需要实现此功能,为此我希望获得您的意见和对可能解决方案的指示。

现在我正在考虑创建我的自定义注释,它将模仿 @PostFilter 并使用相同的语法,但将在我自己的 BaseRepositoryImplementation 中手动调用。在那里,我将从 type 和 Repositories#getRepositoryInformationFor(type)#getRepositoryInterface() 获取存储库接口,找到相应方法的注释并手动调用安全检查。

您是否有不同的解决方案,或者对我提出的解决方案有一些说明?

您是否也知道上述jira 问题是否有时间表?

【问题讨论】:

【参考方案1】:

一种轻量级的方法是使用 hasPermission() 方法并在控制器级别实现您自己的“权限评估器”,如果您愿意的话。

@PreAuthorize("hasPermission(#employee, 'edit')")
public void editEmployee(Employee employee) 
   ...


@Component
public class PermissionEvaluatorImpl implements PermissionEvaluator 
    @Override
    public boolean hasPermission(Authentication auth,
            Object targetDomainObject, Object permission) 
        // return true if "auth" has "permission" permission for the user.
        // Current-user can be obtained from auth.
    
    ...

这里有更详细的描述:http://www.naturalprogrammer.com/spring-domain-object-security-logged-in-user/

【讨论】:

以上是关于在 Spring Data 存储库中包含域对象安全 @PostFilter 可分页端点的主要内容,如果未能解决你的问题,请参考以下文章

如何使用存储库接口在 Spring Data 中通过其嵌套对象的 objectId 查找集合?

具有复杂键的 Spring Data Redis 存储库

如何在 Spring Boot 应用程序的同一个域类上同时使用 Spring Data JPA 和 Spring Data Elasticsearch 存储库?

Spring数据mongodb存储库语法中的@Query注释

保存新对象时反应性存储库抛出异常

如何在 Spring Data 存储库上测试 Spring 的声明式缓存支持?