@PostFilter和@PreFilter如何工作

时间:2015-02-21 16:12:46

标签: java spring spring-security annotations spring-annotations

对于弹簧注释不熟悉,我需要澄清下面的代码。

@PostFilter("hasPermission(filterObject, 'READ') or hasRole('ROLE_ADMIN')")

    public List<User> getUsers(String orderByInsertionDate,
            Integer numberDaysToLookBack) throws AppException

因此,这意味着getUsers返回的用户列表将仅包含对调用对象具有完全"READ"访问权限的元素,或者调用对象具有"ROLE_ADMIN"角色。感谢。

3 个答案:

答案 0 :(得分:15)

指定

@PreFilter@PostFilter与Spring安全性一起使用,以便能够根据授权过滤集合或数组。

要使其正常工作,您需要在spring安全性中使用基于表达式的访问控制(正如您的示例中所示)

@PreFilter - 在执行方法之前过滤集合或数组。

@PostFilter - 在执行方法后过滤返回的集合或数组。

因此,假设您的getUser()返回用户列表。 Spring Security将遍历列表并删除所应用表达式为false的所有元素(例如,不是admin,并且没有读取权限)

filterObject是执行过滤操作的内置对象,您可以对此对象应用各种条件(基本上所有内置表达式都可用,例如principalauthentication),你可以做的例子

@PostFilter ("filterObject.owner == authentication.name")

虽然这些过滤器很有用,但对于大型数据集来说效率非常低,而且基本上你失去了对结果的控制,而Spring控制着结果。

答案 1 :(得分:1)

由于当前接受的答案没有输入@PreFilter,所以这是我的两分钱:

(引用JavaDocs

用于指定方法过滤表达式的注释,该表达式将在调用方法之前进行评估。 要过滤的参数名称是使用filterTarget 属性指定的。这必须是支持remove方法的Java Collection实现。

@PreFilter对方法参数(而不是返回值)进行操作。如果带注释的方法只有一个Collection参数,则可以省略filterTarget注释参数。

答案 2 :(得分:0)

关于@PreFilter@PostFilter的基本原理和影响,其他答案非常清楚。

我只是有义务添加有关方法输出类型的信息-这两个注释都可用于集合,数组,流和地图。请小心使用它们,例如Optional。尽管对我来说,过滤Optional很自然(您认为它是最多包含一个元素的集合),但这将引发以下异常,因为spring-security-core 5.4.1:

java.lang.IllegalArgumentException:过滤器目标必须是集合,数组,映射或流类型,但是是可选的[0]