一、基于注解访问控制
- Spring Security 中提供了一些访问控制的注解,这些注解默认不可用,需要通过 @EnableGlobalMethodSecurity 进行开启后使用,如果设置的条件允许则程序正常执行,反之不允许会报 500(AccessDeniedException异常)
- org.springframework.security.access.AccessDeniedException
@Configuration
@EnableGlobalMethodSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
- @EnableGlobalMethodSecurity开启之后,外有三大注解可以写到 Service 接口或方法上,也可以写到 controller或 controller 的方法上,通常情况下都是写在控制器方法上,控制接口URL是否允许被访问
- 新建annotation.html,用于注解控制
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>SpringBoot Security</title>
</head>
<body>
<h3>欢迎登录SpringBoot Security 注解控制首页</h3>
</body>
</html>
- 在WebSecurityConfigurerAdapter配置类上 @EnableGlobalMethodSecurity 开启注解即可开启全局方法注解功能
二、三大注解控制方法
2.1 @Secured
- @Secured专门用于判断是否具有指定角色,可写在方法或类上,注意参数以 ROLE_ 开头,由于只能判断角色,所以实际中使用并不多
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Secured {
String[] value();
}
- 在 @EnableGlobalMethodSecurity 注解功能类上通过指定参数 securedEnabled = true 开启 @Secured 功能
- @EnableGlobalMethodSecurity(securedEnabled = true)
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
- 在控制器方法上添加@Secured注解,要求具备 ROLE_ADMIN 权限才能访问
@RequestMapping("/toAnnotation")
@Secured("ROLE_ADMIN")
public String annotation() {
return "redirect:/annotation.html";
}
- 在SecurityConfig中配置对应的权限
- successForwardUrl指定到对应的处理器
http.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.successForwardUrl("/toAnnotation");
- 启动项目,然后测试有权限和无权限
2.2 @PreAuthorize
- @PreAuthorize是方法或类级别注解,表示访问方法或类在执行之前先判断权限,大多情况下都是使用这个注解,注解的参数和access()方法参数取值相同,都是权限表达式
- 使用时需要在 @EnableGlobalMethodSecurity 注解功能类上通过指定参数 prePostEnabled= true 开启**@PreAuthorize** 功能
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
- 在控制器方法上添加@PreAuthorize,参数可以是任何 access() 支持的表达式
@RequestMapping("/preAuthorize")
@PreAuthorize("hasRole('ADMIN')")
public String preAuthorize() {
return "redirect:/annotation.html";
}
- 访问接口,分别使用admin和root访问,结果和@Secured一致
- http://localhost:8888/preAuthorize
2.3 @PostAuthorize
- @PostAuthorize是方法或类级别注解,表示方法或类执行结束后判断权限,此注解很少被使用到
- 使用时需要在 @EnableGlobalMethodSecurity 注解功能类上通过指定参数 prePostEnabled= true 开启 @PostAuthorize功能
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
- 在控制器方法上添加@PreAuthorize,参数可以是任何access()支持的表达式
@RequestMapping("/postAuthorize")
@PostAuthorize("hasRole('ADMIN')")
public String postAuthorize() {
return "redirect:/annotation.html";
}
- 访问接口,分别使用admin和root访问,结果和@Secured一致
- http://localhost:8888/postAuthorize
- 由于是方法和类执行结束后才判断的权限,而实际中通常是在执行前做判断,不然权限拦截就没有实际意义