介绍
Spring Security是相对复杂的安全管理框架,下面记录SpringBoot整合Spring Security框架
Spring Security基本配置
第一:导入相关依赖
1.spring-boot-starter-security
2.spring-boot-starter-web
3.mybatis-spring-boot-starter
4.mysql-connector-java
5.druid-spring-boot-starter
第二:配置druid连接池
spring.datasource.url=jdbc:mysql://localhost:3306/security?serverTimezone=UTC
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=root
第三:创建Bean
User类: 实现UserDetails接口,类似规范
public class User implements UserDetails {
private Integer id;
private String username;
private String password;
private Boolean enabled;
private Boolean locked;
private List<Role> roles;
@Override
public String getUsername() {
return username;
}
@Override
public String getPassword() {
return password;
}
/**
* 账户是否未过期
* @return 数据库没配置所以直接true,表示没有过期
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 账户是否未锁定
* @return 数据库中0表示为锁定,所以加一个!匹配
*/
@Override
public boolean isAccountNonLocked() {
return !locked;
}
/**
* 密码是未过期
* @return 数据库没配置所以直接true,表示密码没有过期
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 用户是否可用
* @return 数据库中1代表可用,所以直接返回enabled;
*/
@Override
public boolean isEnabled() {
return enabled;
}
/**
*获取用户所有角色信息,遍历roles集合分别设置
* @return SimpleGrantedAuthority集合
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
for (Role r : roles){
simpleGrantedAuthorities.add(new SimpleGrantedAuthority("ROLE_"+r.getName()));
}
return simpleGrantedAuthorities;
}
//省略getter&setter
}
Role类:
public class Role {
private Integer id;
private String name;
private String nameZh;
//省略getter&setter
}
第四:配置UserService
继承UserDetailsService
@Service
public class UserService implements UserDetailsService {
@Autowired
UserMapper userMapper;
/**
* @param username 登录时输入的用户名在数据库判断是否存在用户,否则抛出UsernameNotFoundException异常
* @return 如果判断无误,直接返回完整user对象
* @throws UsernameNotFoundException 用户未找到异常 后面还是转化为BadCredentialsException异常
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.loadUserByUsername(username);
if (user==null){
throw new UsernameNotFoundException("用户名不存在 ");
}
user.setRoles(userMapper.getUserRolesById(user.getId()));
return user;
}
}
第五:配置接口还有Mapper
UserMapper.class
@Mapper
@Repository
public interface UserMapper {
User loadUserByUsername(String username);
List<Role> getUserRolesById(Integer id);
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org.//DTD Mapper 3.0//EN"
"htttp://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pljandsyx.top.securitydb.mapper.UserMapper">
<select id="loadUserByUsername" parameterType="String" resultType="pljandsyx.top.securitydb.bean.User">
select * from user where username = #{username}
</select>
<select id="getUserRolesById" parameterType="Integer" resultType="pljandsyx.top.securitydb.bean.Role">
select * from role where id in (select rid from user_role where uid = #{uid})
</select>
</mapper>
第六:配置SpringSecurity
创建配置类,extends父类:WebSecurityConfigurerAdapter,实现两个configure方法.
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//注入配置好的UserService类
@Autowired
UserService userService;
/**
* 将配置好的UserService类提供给认证管理工具AuthenticationManagerBuilder,就不需要用内存认证那一套
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
/**
* 加密
* @return
*/
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 在这里配置路径匹配规则,以及角色权限分配,以及各种认证规则
* 关闭csrg防御
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/dba/**").hasRole("dba")
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").hasRole("user")
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.csrf()
.disable();
}
}
第七:角色继承
在Security配置类中添加一个Bean
/**
* 配置RoleHierarchy类,实现角色继承功能
* @return RoleHierarchyImpl 接口实现类
*/
@Bean
RoleHierarchy roleHierarchy(){
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
String hieraarchy = "ROLE_dba > ROLE_admin ROLE_admin > ROLE_user";
roleHierarchy.setHierarchy(hieraarchy);
return roleHierarchy;
}
第八:测试
创建Controller层
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello security";
}
@GetMapping("/admin/hello")
public String adminHello(){
return "hello admin!";
}
@GetMapping("/dba/hello")
public String dbaHello(){
return "hello dba";
}
@GetMapping("/user/hello")
public String userHello(){
return "hello user";
}
}