概述
SpringSecurity 是基于 Spring AOP 和 Servlet 过滤器的安全框架,提供全面的安全性解决方案。
Spring Security核心功能包括 用户认证(Authentication) 、用户授权(Authorization) 和 攻击防护 3 个部分:
- 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程
- 用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限
- 攻击防护即防止伪造身份
基本配置
1、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、web安全配置
通过重写WebSecurityConfigurerAdapter
抽象类,并使用@EnableWebSecurity
注解标注,进行web安全配置
WebSecurityConfigurerAdapter
抽象类有3个重载方法:
protected void configure(AuthenticationManagerBuilder auth) throws Exception
方法同认证相关,比如验证用户的账号密码
protected void configure(HttpSecurity http) throws Exception
方法同授权相关,配置资源(URL)访问权限
public void configure(WebSecurity web) throws Exception
主要用户全局请求忽略规则配置、HttpFirewall配置、debug配置、全局SecurityFilterChain配置
内存认证
Spring Security5.x默认BCrypt加密,加密后的格式为“{加密编码}加密后的密码”
下述代码是明文密码实现方式:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 明文密码
auth.inMemoryAuthentication().withUser("user").password("{noop}123456").roles();
}
}
BCrypt加密:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 明文密码
//auth.inMemoryAuthentication().withUser("user").password("{noop}123456").roles();
auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("123456")).roles();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
数据库认证
当Spring Security处理认证时,前台提交的账号密码会被封装为Authentication
对象,并与UserDetails
对象比较。
UserDetails
对象储存用户正确的认证信息,该对象通过UserDetailsService
接口的loadUserByUsername
方法加载相关信息
如果用户密码储存在数据库,则要实现UserDetailsService
接口:
@Service
public class CustomUserDetailService implements UserDetailsService {
@Autowired
private UserInfoService userInfoService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userInfoService.findByUsername(username);
if (userInfo == null) {
throw new UsernameNotFoundException("not found");
}
// 定义权限列表
List<GrantedAuthority> authorities = new ArrayList<>();
// 用户所拥有的权限 必须以 ROLE_ 开头
authorities.add(new SimpleGrantedAuthority("ROLE_" + userInfo.getRole()));
User userDetails = new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
return userDetails;
}
}