在 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 Boot 应用程序的同一个域类上同时使用 Spring Data JPA 和 Spring Data Elasticsearch 存储库?