SpringBoot 集成 SpringSecurity 详解(五)-- 基于内存实现角色授权
需求缘起
前面我们实现了基于内存或者基于MySQL数据库实现了多用户登录,在实际应用中,每个用户的角色往往都是不同的,比如有的是普通会员,有的是超级会员,还有的是管理员,每个角色所能访问的方法也是不一样的,那我们该怎么去区别他们呢?这就是本节所要解决的问题,通过角色授权的方式,每种角色有自己的权限,每个方法也有自己的权限,当只有方法的权限和角色的权限匹配时方可访问。这就可以实现了不同角色访问不同的方法。
这一节我们在第三节的基础上,来实现基于内存实现角色授权。
技术要点
1.开启方法安全级别的控制
2.授予指定用户角色
3.配置方法级别的权限控制
一、开启方法安全级别的控制
在类SecurityConfig 上添加配置
@Configuration
@EnableWebSecurity//开启Spring Security的功能
@EnableGlobalMethodSecurity(prePostEnabled=true)//开启方法安全级别的控制
public class SecurityConfig extends WebSecurityConfigurerAdapter {
......
}
二、授予指定用户角色
通过AuthenticationManagerBuilder的roles()方法分配角色:
@Configuration
@EnableWebSecurity//开启Spring Security的功能
@EnableGlobalMethodSecurity(prePostEnabled=true)//开启方法安全级别的控制
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
//SpringSecurity 提供的一种编码器,我们也可以自己实现PasswordEncoder
return new BCryptPasswordEncoder();
}
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//通过内存创建用户名、密码和权限
auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder.encode("123456")).roles("ADMIN");
auth.inMemoryAuthentication().withUser("user").password(passwordEncoder.encode("123456")).roles("USER");
}
}
三、配置方法级别的权限控制
在控制器 HelloSecurityController 中添加两个方法,如下:
@RestController
@RequestMapping("/hello")
public class HelloSecurityController {
@GetMapping
public String hello() {
return "Hello Spring Security!";
}
/**
* 在这里例子中 用户 ADMIN和 USER 都能访问这个接口
* @return
*/
@GetMapping("/helloUser")
@PreAuthorize("hasAnyRole('ADMIN','USER')")//访问这个接口需要有 ADMIN或者USER的权限的用户才能访问
public String user() {
return "Hello,user";
}
/**
* 在这里例子中 用户 USER是不能访问这个接口的,会报权限不足异常
* @return
*/
@GetMapping("/helloAdmin")
@PreAuthorize("hasAnyRole('ADMIN')")//访问这个接口需要有 ADMIN的权限的用户才能访问
public String admin() {
return "Hello,admin";
}
}
提示: 只有在系统中添加了@EnableGlobalMethodSecurity(prePostEnabled=true)之后,@PreAuthorize(“hasAnyRole(‘ADMIN’)”)才会生效。
四、测试
1. 重启应用,访问http://localhost:8080/hello/helloUser,输入用户名 “user” 和 密码 “123456”,不出意外将会顺利访问,返回 “Hello,user”;
2. 此时再去访问 http://localhost:8080/hello/helloAdminr,会报403异常,因为这个接口用户"user"是没有权限访问的;
3. 重启应用,访问http://localhost:8080/hello/helloUser,输入用户名 “admin” 和 密码 “123456”,不出意外将会顺利访问,返回 “Hello,user”,因为这个接口用户"admin"也有权限访问;
4. 此时再去访问 http://localhost:8080/hello/helloAdminr,会发现也能顺利访问,因为这个接口用户"admin"有权限访问;