1、引入maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
项目结构
2、在config包下面创建一个配置类SecurityConfigTest继承WebSecurityConfigurerAdapter
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(password());
}
@Bean
PasswordEncoder password() {
return new BCryptPasswordEncoder();
}
/**
* 自定义登录跳转的页面及角色权限
*
* @param http
*/
@Override
protected void configure(HttpSecurity http) {
try {
//配置退出的路径
http.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/test/hello")
.permitAll();
//配置登录
http.formLogin()
.loginPage("/login.html")//登录页面设置
.loginProcessingUrl("/user/login")//登录访问路径
.defaultSuccessUrl("/test/index")//登录成功之后,跳转的路径
.and().authorizeRequests()
.antMatchers("/", "/test/hello", "/test/index", "/user/login").permitAll()//设置哪些路径是不需要拦截的
.antMatchers("/test/index").hasAnyAuthority("admins,manager")//hasAnyAuthority基于资源的权限控制,匹配任意一个符合条件的即可
// .antMatchers("/test/role").hasAnyRole("sale")//基于角色的权限控制,匹配任意角色即可
.anyRequest().authenticated()
.and().csrf().disable();
} catch (Exception e) {
e.printStackTrace();
}
}
}
一般建议使用的是对资源进行授权,不建议对角色进行授权
3、创建MyUserDetailService实现Security里面的UserDetailsService接口
@Service("userDetailService")
public class MyUserDetailService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<Users> wrapper = new QueryWrapper<>();
wrapper.eq("username", username);
Users users = userMapper.selectOne(wrapper);
if (users == null) {
throw new UsernameNotFoundException("用户不存在");
}
//角色控制,需要添加一个前缀ROLE
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");
return new User(users.getUsername(), new BCryptPasswordEncoder().encode(users.getPassword()), auths);
}
}
基于角色控制的时候需要在角色的前面添加一个ROLE_不然识别不了。
mapper编写
@Mapper
@Repository
public interface UserMapper extends BaseMapper<Users> {
}
以上是介于配置类的方式来进行权限的管理,还以使用注解的方式来做权限管理
开启注解模式
@SpringBootApplication
//securedEnabled = true,开启security注解模式,prePostEnabled = true,在方法之前和之后执行校验
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SecurityDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityDemoApplication.class, args);
}
}
创建配置类
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(password());
}
@Bean
PasswordEncoder password() {
return new BCryptPasswordEncoder();
}
/**
* 自定义登录跳转的页面及角色权限
*
* @param http
*/
@Override
protected void configure(HttpSecurity http) {
try {
//配置退出的路径
http.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/test/hello")
.permitAll();
//配置登录
http.formLogin()
.and().authorizeRequests()
.antMatchers("/", "/test/hello", "/test/index", "/user/login").permitAll()//设置哪些路径是不需要拦截的
.anyRequest().authenticated()
.and().csrf().disable();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在Ctroller中添加注解
@RestController
@RequestMapping("/test")
public class HelloController {
@GetMapping("/index")
public String index() {
return "index";
}
@GetMapping("/role")
public String role() {
return "role";
}
@GetMapping("/update")
// @Secured({"ROLE_sale","ROLE_manager"})//基于角色可以访问
@PreAuthorize("hasAnyAuthority('admins') and hasAnyAuthority('read_account') ")//基于资源的权限访问,在方法执行之前进行校验
// @PostAuthorize("hasAnyAuthority('admins')") //基于资源的权限访问,在方法执行之后进行校验
public String update() {
return "update";
}
}
如果需要对返回的结果进行过滤后返回,可以使用@PostFilter()
在返回的集合中,只有username=admin1的数据才会返回
如果需要对传入发参数集合进行筛选之后才调用方法,可以使用@PreFilter(),
在参数集合list中,只有id等于偶数的才能访问