对于弹簧注释不熟悉,我需要澄清下面的代码。
@PostFilter("hasPermission(filterObject, 'READ') or hasRole('ROLE_ADMIN')")
public List<User> getUsers(String orderByInsertionDate,
Integer numberDaysToLookBack) throws AppException
因此,这意味着getUsers返回的用户列表将仅包含对调用对象具有完全"READ"
访问权限的元素,或者调用对象具有"ROLE_ADMIN"
角色。感谢。
答案 0 :(得分:15)
@PreFilter
和@PostFilter
与Spring安全性一起使用,以便能够根据授权过滤集合或数组。
要使其正常工作,您需要在spring安全性中使用基于表达式的访问控制(正如您的示例中所示)
@PreFilter - 在执行方法之前过滤集合或数组。
@PostFilter - 在执行方法后过滤返回的集合或数组。
因此,假设您的getUser()
返回用户列表。 Spring Security将遍历列表并删除所应用表达式为false的所有元素(例如,不是admin,并且没有读取权限)
filterObject是执行过滤操作的内置对象,您可以对此对象应用各种条件(基本上所有内置表达式都可用,例如principal
,authentication
),你可以做的例子
@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]