目录
1 @EnableGlobalMethodSecurity
@EnableGlobalMethodSecurity
是 Spring Security
中的一个注解,用于启用全局方法安全性。
其中属性prePostEnabled
和securedEnabled
都是它的属性,分别表示是否允许使用@PreAuthorize
和@Secured
注解来控制方法的访问权限。
当prePostEnabled
为true
时,表示允许使用@PreAuthorize
和@Secured
注解来控制方法的访问权限;当securedEnabled
为true
时,表示允许使用@Secured
注解来控制方法的访问权限。
点击此处了解 SpringSecurity和JWT实现认证和授权
1.1 @PreAuthorize
@PreAuthorize
是 Spring Security
提供的注解之一,用于在方法执行之前进行权限验证。通过使用 @PreAuthorize
注解,可以在方法级别对用户的权限进行校验,只有具备相应权限的用户才能执行被注解的方法。
@PreAuthorize
注解会在方法执行前进行权限验证,支持Spring EL
表达式,它是基于方法注解的权限解决方案
1.1.1 开启注解
在SpringSecurity
配置类上添加 @EnableGlobalMethodSecurity(prePostEnabled = true)
注解,以开启方法级别的权限验证,并支持 @PreAuthorize
注解。
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
1.1.2 使用注解原生方法
在方法上添加 @PreAuthorize
注解:找到需要进行权限验证的方法,在方法上添加 @PreAuthorize
注解,并指定相应的权限表达式
@PreAuthorize
注解支持丰富的权限表达式,可以根据具体的需求进行配置。例如,可以使用 hasRole('ROLE_ADMIN')
来验证用户是否具备指定角色,或者使用 hasAuthority('PERMISSION_ADD_USER')
来验证用户是否具备指定权限。
通过使用 @PreAuthorize
注解,可以对方法进行细粒度的权限控制,确保只有授权的用户才能执行对应的方法。
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void adminOnlyMethod(){
}
1.1.3 使用注解自定义方法
@GetMapping("/{reportId}" )
@PreAuthorize("@test.hasPermission('archsys_sysarchreport_view')" )
public R getById(@PathVariable("reportId" ) Long reportId) {
return R.ok(sysArchReportService.getById(reportId));
}
@PreAuthorize("@test.hasPermission('archsys_sysarchreport_view')" )
test
:是一个注册在Spring
容器中的Bean
,对应的类是 cn.test.PermissionService;
hasPermission
是PermissionService
类中定义的方法;
当Spring EL 表达式返回TRUE,则权限校验通过;
PermissionService.java的定义如下:
@Service("test")
public class PermissionService {
public boolean hasPermission(String... permissions) {
if (ArrayUtil.isEmpty(permissions)) {
return false;
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
return false;
}
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
return authorities.stream().map(GrantedAuthority::getAuthority).filter(StringUtils::hasText)
.anyMatch(x -> PatternMatchUtils.simpleMatch(permissions, x));
}
}
1.2 @PostAuthorize
在方法执行后再进行权限校验,适合验证带有返回值的权限
先要开启注解功能
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
使用
@PostAuthorize("hasAnyAuthority('write')")
@RequestMapping(value = "/testPostAuthorize")
@ResponseBody
public String postAuthorize() {
System.out.println("方法进入了。。。。");
return "preAuthorize";
}
1.3 @Secured
判断是否具有角色,注意这里匹配的字符串需要添加前缀ROLE_
开启注解功能
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
在控制器方法上添加注解
@Secured({"ROLE_read"})
@RequestMapping(value = "/testSecured")
@ResponseBody
public String testSecured() {
return "testSecured";
}
2 其他注解
2.1 @PostFilter
@PostFilter
是Spring Security
框架中的一个注解,用于在请求处理之后对请求进行过滤。
该注解可以应用于方法级别或类级别,用于指定只有满足特定条件的请求才能通过过滤器。例如,我们可以使用@PostFilter
注解来限制只有经过身份验证的用户才能访问某个接口。
在方法级别上,@PostFilter
注解的语法如下:
@RestController
public class MyController {
@PostFilter("hasRole('ADMIN')")
@GetMapping("/admin")
public String admin() {
// ...
}
}
其中,hasRole('ADMIN')
是一个预定义的条件表达式,表示只有拥有ADMIN
角色的用户才能访问该方法。如果用户没有该角色,则无法访问该方法。
2.2 @PreFilter
进入控制器之前对数据进行过滤
@PreFilter
是 Spring Security
框架中的一个注解,用于在请求处理之前
对请求进行过滤。
该注解可以应用于方法级别或类级别,用于指定只有满足特定条件的请求才能通过过滤器。例如,我们可以使用@PreFilter
注解来限制只有拥有特定角色的用户才能访问某个接口。
在方法级别上,@PreFilter注解的语法如下:
@RequestMapping("/getTestPreFilter")
@PreFilter("hasRole('ADMIN')")
@ResponseBody
public List<UserPO> getTestPreFilter(@RequestBody List<UserPO> list) {
list.forEach(t -> {
System.out.println(t.getId() + "\t" + t.getUsername());
});
return list;
}
3 权限表达式
在Spring Security
中,权限表达式
是一种控制访问权限的方式。它可以通过方法级别的注解@PreAuthorize
、@PostAuthorize
、@PreFilter
和@PostFilter
来实现。其中,@PreAuthorize
和@PostAuthorize
注解用于控制方法级别
的访问权限,而@PreFilter
和@PostFilter
注解用于控制请求级别
的过滤。
除了这些注解之外,Spring Security
还提供了一些其他的注解和类来实现权限控制。例如,可以使用WebExpressionVoter
类来解析权限表达式,并根据表达式的结果来判断用户是否拥有对应的权限。此外,还可以使用SecurityExpressionRoot
类来构建表达式,并将其应用于URL路径或方法上。