前言
之前security中,针对配置项进行了相关的配置和测试。
但是这些都是基于在
security.config.MyConfig#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
中进行对应请求的权限限制
。
如果是多个请求,各个有不同的配置项,依旧还采取configure(HttpSecurity http)
的配置方式,将会有很多的不便之处。
本次测试
本篇博客主要说明,如何采取注解
的方式,实现不同请求不同权限设定
的配置和测试。
注解介绍
在配置和设置操作之前,先大致介绍下几种注解的用途。
- 1、@Secured
判断主体是否具备角色访问方法。需要注意匹配的字符串需要增加前缀 ROLE_
。 - 2、@PreAuthorize
适用于进入方法前的权限验证,
可以将登录用户的roles / permissions
参数
传到方法中
。 - 3、@PostAuthorize (
用的较少
)
在方法执行后
进行权限校验
,适合验证带有返回值的权限。 - 4、@PostFilter
权限验证通过后,留下指定用户名的数据。 - 5、@PreFilter
对传递参数值做过滤。
注解使用
@Secured
判断主体是否具备角色访问方法。需要注意匹配的字符串需要增加
前缀 ROLE_
。
在使用注解
配置之前,需要先在启动类上开启注解支持
。
@EnableGlobalMethodSecurity(securedEnabled = true) //开启 security 对方法上增加权限的功能
编写测试接口,使用注解限定接口访问权限:
@RequestMapping("/update")
@Secured({"ROLE_admin","ROLE_user"})
public String update(){
return "security test 5 update 需要验证的接口";
}
@RequestMapping("/delete")
@Secured({"ROLE_delete"})
public String delete(){
return "security test 5 delete 需要验证的接口";
}
在security.service.MySecurityService#loadUserByUsername
中设定用户权限
信息。
List<GrantedAuthority> admin =
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_user,ROLE_admin,admin");
由于登录角色设定有ROLE_user
、ROLE_admin
、admin
三种权限。
接口
/update
需要角色为ROLE_admin
和ROLE_user
。
接口/delete
需要角色为ROLE_delete
。
从设置权限上来看,/update
是可以访问,但/delete
会因为无权,无法访问。
请求测试:
http://localhost/update
http://localhost/delete
@PreAuthorize
适用于进入方法前的权限验证,
可以将登录用户的roles / permissions
参数
传到方法中
。
在配置之前,必须在启动类上增加下列注解:
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启 security 对方法上增加权限的功能
如果存在使用其他注解的情况,可以使用下列注解方式:
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) //开启 security 对方法上增加权限的功能
编写测试controller接口:
@RequestMapping("/updateBefore")
//@PreAuthorize("hasRole('ROLE_admin')")
//@PreAuthorize("hasAnyRole('ROLE_admin','ROLE_user')")
//@PreAuthorize("hasAuthority('admin')")
@PreAuthorize("hasAnyAuthority('admin','update')") // 注意单引号
public String updateBefore(){
return "security test 5 updateBefore 需要验证的接口";
}
检查登录账户的配置角色信息:
请求测试:
http://localhost/updateBefore
@PostAuthorize
在
方法执行后
进行权限校验
,适合验证带有返回值的权限。
在测试之前,必须保证启动类上包含下列注解,保证注解的正常使用:
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启 security 对方法上增加权限的功能
如果存在使用其他注解的情况,可以使用下列注解方式:
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) //开启 security 对方法上增加权限的功能
编写对应的测试接口:
@RequestMapping("/updateAfter")
@PostAuthorize("hasAnyRole('ROLE_update')") // 未配置 ROLE_update 权限
public String updateAfter(){
log.info("=== 进入当前 updateAfter ====");
return "security test 5 updateAfter 需要验证的接口";
}
查看配置权限中的登录角色的权限信息:
请求测试:
http://localhost/updateAfter
查看控制台:
@PostFilter
权限验证通过后,留下指定用户名的数据。
对返回数据做过滤
编写请求接口:
@RequestMapping("/postFilter")
@PreAuthorize("hasAnyAuthority('admin','update')") // 注意单引号
@PostFilter("filterObject.username == 'xiangjiao'") // 针对返回数据做过滤
public List<User> postFilter(){
log.info("=== 进入当前 postFilter ====");
List<User> userLists = new ArrayList<>();
userLists.add(new User(1,"xiangjiao","bunana",1,0));
userLists.add(new User(2,"xiangjiao2","bunana2",1,0));
return userLists;
}
上面封装数据结果有两个!
请求:
http://localhost/postFilter
本来是两条数据,但是只返回了一条,
@PostFilter(“filterObject.username == ‘xiangjiao’”) 只针对 username 为 xiangjiao 的数据进行返回!
@PreFilter
对传递参数值做过滤。
编写请求接口:
@PostMapping("/preFilter")
@PreAuthorize("hasAnyAuthority('admin','update')") // 注意单引号
@PreFilter("filterObject.id % 2 == 0") // id为偶数才能请求
public String preFilter(@RequestBody List<User> userLists){
log.info("=== 进入当前 preFilter ====");
log.info(userLists.toString());
return "security test 5 preFilter 需要验证的接口";
}
暂未测试,因为前后分离还未深入研究,后期补上!
代码下载
springboot-security-08