SpringBoot - 安全管理框架Spring Security使用详解10(通过注解配置方法安全)
在之前的文章样例中,认证和授权都是基于 URL 的。开发者也可以通过注解来灵活地配置方法安全,下面通过样例进行演示。
(2)开启注解安全配置后,接着创建一个 MethodService 进行测试:
(3)最后在 Controller 中注入这个 Service 并调用 Service 中的方法进行测试:
十、通过注解配置方法安全
1,样例代码
(1)首先我们要通过 @EnableGlobalMethodSecurity 注解开启基于注解的安全配置:
@EnableGlobalMethodSecurity 注解参数说明:
- prePostEnabled = true 会解锁 @PreAuthorize 和 @PostAuthorize 两个注解。顾名思义,@PreAuthorize 注解会在方法执行前进行验证,而 @PostAuthorize 注解会在方法执行后进行验证。
- securedEnabled = true 会解锁 @Secured 注解。
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { // 指定密码的加密方式 @SuppressWarnings("deprecation") @Bean PasswordEncoder passwordEncoder(){ // 不对密码进行加密 return NoOpPasswordEncoder.getInstance(); } // 配置用户及其对应的角色 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("root").password("123").roles("DBA") .and() .withUser("admin").password("123").roles("ADMIN") .and() .withUser("hangge").password("123").roles("USER"); } // 配置 URL 访问权限 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 开启 HttpSecurity 配置 .anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问) .and().formLogin().loginProcessingUrl("/login").permitAll() // 开启表单登录并配置登录接口 .and().csrf().disable(); // 关闭csrf } }
(2)开启注解安全配置后,接着创建一个 MethodService 进行测试:
@Service public class MethodService { // 访问该方法需要 ADMIN 角色。注意:这里需要在角色前加一个前缀"ROLE_" @Secured("ROLE_ADMIN") public String admin() { return "hello admin"; } // 访问该方法既要 ADMIN 角色,又要 DBA 角色 @PreAuthorize("hasRole('ADMIN') and hasRole('DBA')") public String dba() { return "hello dba"; } // 访问该方法只需要 ADMIN、DBA、USER 中任意一个角色即可 @PreAuthorize("hasAnyRole('ADMIN','DBA','USER')") public String user() { return "hello user"; } }
(3)最后在 Controller 中注入这个 Service 并调用 Service 中的方法进行测试:
@RestController public class HelloController { @Autowired MethodService methodService; @GetMapping("/admin") public String admin() { return methodService.admin(); } @GetMapping("/dba") public String dba() { return methodService.dba(); } @GetMapping("/user") public String user() { return methodService.user(); } }
2,运行测试
(1)使用 admin 用户登录,无论访问 /admin 接口、还是 /user 接口都是没问题的:
(2)而对于 /dba 接口虽然 admin 也有权限,但该接口内部调用的 methodService.dba() 方法同时需要 ADMIN 和 DBA 权限,因此访问会被拒绝。