Spring Security应用开发(18)基于方法的授权过滤

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Security应用开发(18)基于方法的授权过滤相关的知识,希望对你有一定的参考价值。

本文将介绍@PreFilter@PostFilter这两个注解。

 

@PreFilter

@PreFilter用于对方法的参数进行过滤。这种情况下参数通常是集合类型,符合条件的值被保留在集合中,不符合条件的从集合中移除。如果有多个集合类型的参数,需要使用@PreFilter的一个属性filterTarget来指定要过来的参数的名称。

 

@PostFilter

@PostFilter用于对方法的结果进行过滤。这种情况下返回值通常是集合类型,符合条件的值被保留在集合中,不符合条件的从集合中移除。

 

@PreFilter注解的定义如下所示:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PreFilter {
public String value();
public String filterTarget() default "";
}

从上述定义可以看到,这些注解除了可以使用在方法上之外,还可以使用到类型上。

 

本文给出一个实例:

(1)编写集合中的元素类型的定义。

/**
* @ClassName: UserBean
* @Description:
* @author http://www.cnblogs.com/coe2coe/
* @date 2017年5月30日 下午9:12:46
*  
*/
public class UserBean {

public UserBean(String name, int salary) {
super();
this.name = name;
this.salary = salary;
}

private String name;
private int    salary;

public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } @Override public String toString() { return "UserBean [name=" + name + ", salary=" + salary + "]"; } }

 

 

(2)定义待授权的类和方法。

定义该类和方法,并在该方法上定义@PreFilter@PostFilter注解。目标是先过滤参数salaryList,只保留其中salary>1000的元素,再过滤返回值,只保留其中name属性的长度大于3的元素。

public class UserService {

@PreFilter( filterTarget="salaryList" , value="filterObject > 1000" )
@PostFilter( "filterObject.name.length()>3")
public List<UserBean>  getUsers(List<String> nameList,List<Integer> salaryList){

List<UserBean>  users = new ArrayList<UserBean>();
for(int i=0;i<nameList.size()&&i<salaryList.size();i++){
users.add(new UserBean(nameList.get(i),salaryList.get(i) ) );
}

return users;
}

}

 

 

(3)定义调用该方法的控制器方法。

@RequestMapping("/")
public ModelAndView  index(){
ModelAndView  mv = new ModelAndView();
mv.addObject("message", "Hello,welcome!");
mv.setViewName("home/index");
 

//准备了4个元素的集合。
List<String> nameList = new ArrayList<String>();
List<Integer> salaryList = new ArrayList<Integer>();

nameList.add("zhangsan");
nameList.add("lisi");
nameList.add("wangwu");
nameList.add("li");
 
salaryList.add(10);
salaryList.add(1001);
salaryList.add(2000);
salaryList.add(3000);
 
List<UserBean> users = this.userService.getUsers(nameList,salaryList);

//测试用途,仅仅输出到控制台。
System.out.println(users);

return mv;

}

 

 

(4)运行结果:

最后返回值的结果是3个元素的集合。

控制台输出如下:

[UserBean [name=zhangsan, salary=1001], UserBean [name=lisi, salary=2000], UserBean [name=wangwu, salary=3000]]

 

本文为了测试@PreFilter注解的filterTarget属性的用法,被测试的方法使用了两个参数。由于filterTarget属性只能指定一个参数,同时同一个方法上只能定义唯一一个@PreFilter注解,因此getUsers()方法实际看到的参数中,nameList4个元素,salaryList3个元素,造成了错位。实际应用时,可将nameListsalaryList合并为一个集合,这样就能充分发挥@PreFilter的效果。

关于注解的可重复使用问题,请参考博客Java重要技术(17)注解之注解的重复使用

 



以上是关于Spring Security应用开发(18)基于方法的授权过滤的主要内容,如果未能解决你的问题,请参考以下文章

基于某些标头值跳过 Spring Flux Security

Grails 和 Spring Security 插件:基于角色登录时重定向用户

Spring Security应用开发(20)基于方法的授权使用@RolesAllowed注解

Spring Security应用开发(19)基于方法的授权AOP

Spring Security Reactive WebFilterChainProxy 仅调用单个过滤器链

Spring Security应用开发(17)基于方法的授权评估