使用注解需要开启注解功能
securedEnabled = true:开启Secured注解
prePostEnabled = true:开启Prexxx和Postxxx注解
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)可以放在启动类上,也可以放在配置类上,二选一
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SpringBootWebMvcApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebMvcApplication.class, args);
}
}
使用注解非必要的情况下不要在授权的config方法内设置访问权限了,此方法内就配置登录、注销、记住我
@EnableWebSecurity //开启 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired UserDetailsService userDetailsServiceImpl; //认证:登录验证和设置权限(包含角色和权限) @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(new BCryptPasswordEncoder()); } //授权:针对url的设置 @Override protected void configure(HttpSecurity http) throws Exception { http.exceptionHandling().accessDeniedPage(""); http.authorizeRequests() //.antMatchers("/test/**").hasRole("guest") //.antMatchers("/admin/**").hasRole("admin") .anyRequest().authenticated() .and().formLogin(); } }
@Secured
判断是否具有角色,角色字符串需要添加"ROLE_"前缀
@RestController @RequestMapping("/admin") public class AdminController { @GetMapping("/index") public String index(){ return "Hello Admin"; } @GetMapping("/add") @Secured("ROLE_admin","ROLE_角色名") public String add(){ return "添加方法"; } }
@PreAuthorize、@PostAuthorize
方法执行前后进行权限检查
@PreAuthorize("hasAnyAuthority('权限名','')")
@PreAuthorize("hasAuthority('权限名')")
@PreAuthorize("hasRole('ROLE_角色名')") 或者 @PreAuthorize("hasRole('角色名')")
@PreAuthorize("hasAnyRole('ROLE_角色名','ROLE_角色名')")
@GetMapping("/index") @PreAuthorize("hasAnyAuthority('part','')") public String index(){ return "Hello index"; }
使用表达式
/** * 限制只能查询Id小于10的用户 * * http://localhost:8080/test/find/name */ @GetMapping("/find/{username}") @PreAuthorize("principal.username.equals(#uname)") public String find(@PathVariable("username") String uname) { System.out.println("find user by username......" + uname); return uname; } /** * 限制只能查询自己的信息 * * http://localhost:8080/test/findByid?id=1 */ @GetMapping("/findByid") @PreAuthorize("#id<10") public String findByid(@RequestParam("id") int id) { System.out.println("find user by username......" + Integer.toString(id)); return Integer.toString(id); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/test/add" method="post"> 用户名: <input type="text" name="username"/> <input type="submit" value="submit"/> </form> </body> </html>
/** * 限制只能新增用户名称为abc的用户 */ @PostMapping("/add") @PreAuthorize("#user.username.equals('abc')") public void add(Users user) { System.out.println("addUser............" + user); }
@PostAuthorize使用表达式
可以通过returnObject获取方法的返回值
/** * http://localhost:8080/test/find/guest * http://localhost:8080/test/find/abc */ @GetMapping ("/find/{username}") @PostAuthorize("returnObject.username.equals('abc')") public Users find(@PathVariable("username") String username) { Users user = new Users(); user.setUsername(username); System.out.println(username); return user; }
在方法执行完成后进行权限检查,如果返回值的username属性值是abc校验通过,否则校验失败抛出AccessDeniedException。
注意:@PostAuthorize注解不能控制方法的执行,执行完成后校验失败会抛出AccessDeniedException。
@PreFilter、@PostFilter
集合类型的参数、返回值进行过滤
返回值过滤
/** * http://localhost:8080/test/findAll */ @GetMapping("findAll") @PostFilter("filterObject.id%2==0") public List<Items> findAll() { List<Items> itemList = new ArrayList<Items>(); itemList.add(new Items(1,"华为")); itemList.add(new Items(2,"小米")); return itemList; }
参数过滤
<form action="/test/batchProcess" method="post"> id: <input type="text" name="ids" value="1"/> id: <input type="text" name="ids" value="3"/> 用户名: <input type="text" name="usernames" value="name1"/> 用户名: <input type="text" name="usernames" value="name2"/> <input type="submit" value="submit"/> </form>
filterObject:集合中的对象。
@PreFilter注解的方法拥有多个集合类型的参数时,需要通过filterTarget属性指定参数进行过滤
@PostMapping("/batchProcess") @PreFilter(filterTarget = "ids", value = "filterObject%3==0") public void batchProcess(@RequestParam(value = "ids") List<Integer> ids,@RequestParam(value = "usernames") List<String> usernames) { System.out.println(ids); System.out.println(usernames); }