概述
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;
}
}