当前位置: > > > SpringBoot - 安全管理框架Spring Security使用详解10(通过注解配置方法安全)

SpringBoot - 安全管理框架Spring Security使用详解10(通过注解配置方法安全)

    在之前的文章样例中,认证和授权都是基于 URL 的。开发者也可以通过注解来灵活地配置方法安全,下面通过样例进行演示。 

十、通过注解配置方法安全

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() 方法同时需要 ADMINDBA 权限,因此访问会被拒绝。
评论0