简体   繁体   English

@PostFilter 和 @PreFilter 如何在 Spring Security 中工作?

[英]How do @PostFilter and @PreFilter work in Spring Security?

Being new to Spring's security annotations, I need a clarification for the below code.作为 Spring 安全注释的新手,我需要对以下代码进行说明。

@PostFilter("hasPermission(filterObject, 'READ') or hasRole('ROLE_ADMIN')")
public List<User> getUsers(String orderByInsertionDate,
            Integer numberDaysToLookBack) throws AppException

So this means that the list of users returned by getUsers will only contain those elements which have full "READ" access to the calling object or the calling object has role as "ROLE_ADMIN" .因此,这意味着 getUsers 返回的用户列表将仅包含对调用对象具有完全"READ"访问权限或调用对象具有角色为"ROLE_ADMIN"那些元素。 Thanks.谢谢。

@PreFilter and @PostFilter are designated to use with Spring security to be able to filter collections or arrays based on the authorization. @PreFilter@PostFilter被指定与 Spring 安全一起使用,以便能够根据授权过滤集合或数组。

To have this working, you need to use expression-based access control in spring security (as you have in your example)要使其正常工作,您需要在 spring 安全性中使用基于表达式的访问控制(如您的示例中所示)

@PreFilter - filters the collection or arrays before executing method. @PreFilter - 在执行方法之前过滤集合或数组。

@PostFilter - filters the returned collection or arrays after executing the method. @PostFilter - 执行方法后过滤返回的集合或数组。

So, let's say your getUser() returns List of Users.因此,假设您的getUser()返回用户列表。 Spring Security will iterate through the list and remove any elements for which the applied expression is false (eg is not admin, and does not have read permission) Spring Security 将遍历列表并删除任何应用表达式为 false 的元素(例如,不是管理员,并且没有读取权限)

filterObject is built-in object on which filter operation is performed and you can apply various conditions to this object (basically all built-in expressions are available here, eg principal , authentication ), for example you can do filterObject 是执行过滤操作的内置对象,您可以对这个对象应用各种条件(基本上所有内置表达式都在这里可用,例如principalauthentication ),例如您可以这样做

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

Though those filters are useful, it is really inefficient with large data sets, and basically you lose control over your result, instead Spring controls the result.尽管这些过滤器很有用,但对于大数据集来说确实效率低下,而且基本上你失去了对结果的控制,取而代之的是 Spring 控制结果。

Since the currently accepted answer didn't go into @PreFilter, here's my two cents:由于当前接受的答案没有进入@PreFilter,这是我的两分钱:

(Quote from the JavaDocs ) (引用自JavaDocs

Annotation for specifying a method filtering expression which will be evaluated before a method has been invoked.用于指定方法过滤表达式的注释,该表达式将在调用方法之前进行评估。 The name of the argument to be filtered is specified using the filterTarget attribute.要过滤的参数的名称是使用 filterTarget属性指定的 This must be a Java Collection implementation which supports the remove method.这必须是支持 remove 方法的 Java 集合实现。

@PreFilter operates on the method arguments, not the return value. @PreFilter 操作方法参数,而不是返回值。 If the annotated method only has a single Collection argument, then the filterTarget annotation argument can be omitted.如果带注释的方法只有一个 Collection 参数,则可以省略 filterTarget 注释参数。

The other answers are pretty clear about the rationale and effects of @PreFilter and @PostFilter .其他答案非常清楚@PreFilter@PostFilter的基本原理和效果。

I just feel obliged to add an information about the method output type - both these annotations work with collections, arrays, streams and maps .我只是觉得有必要添加有关方法输出类型的信息——这两个注释都适用于集合、数组、流和映射 Be careful to use them with for example Optional .小心使用它们,例如Optional Although to me it's pretty natural to filter an Optional (you think of it as of the collection with at most one element), this will throw the following exception since spring-security-core 5.4.1:虽然对我来说过滤一个Optional是很自然的(你认为它是最多包含一个元素的集合),但从 spring-security-core 5.4.1 开始,这将抛出以下异常:

java.lang.IllegalArgumentException: Filter target must be a collection, array, map or stream type, but was Optional[0] java.lang.IllegalArgumentException: 过滤器目标必须是集合、数组、映射或流类型,但为 Optional[0]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM