一:前言
(1)Spring Security概念:
Spring Security 是屬于 Spring 生態下一個功能強大且高度可定制的認證和授權框架,它不僅限于 Web 應用程序的安全性,也可以用于保護任何類型的應用程序。
(2)場景描述:
當前端請求 /login 接口,后端并沒有對登錄接口有@PostMapping("/login")的注解,且框架中有使用Spring Security當做權限校驗框架。原因是Spring Security有自動處理解析 /login 接口功能
二:思路整理分析
(1)官方文檔
在Spring Security默認幫我們處理了登錄、登出等接口
文檔地址:表單登錄 :: Spring Security
(2)主要思路:
①前端請求 POST /login,瀏覽器將請求重定向到登錄頁面
②Spring Security 的 UsernamePasswordAuthenticationFilter 攔截,然后提取username 和 password
③調用配置的 UserDetailsService 實例的 loadUserByUsername(username)
④如果返回 UserDetails,繼續密碼比對(PasswordEncoder)
⑤成功 → 認證成功,生成 SecurityContext,失敗 → 拋出異常(如 UsernameNotFoundException)
三:步驟實現
(1)關鍵配置
代碼參考如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(auth -> auth.requestMatchers("/login").permitAll().anyRequest().authenticated()).formLogin(Customizer.withDefaults()) // 使用默認表單登錄.csrf().disable(); // 為了測試方便關掉 CSRF(生產不建議)return http.build();}@Beanpublic UserDetailsService userDetailsService() {return new CustomUserDetailsService(); // 自定義實現}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
(2)繼承實現UserDetailsService 接口,重寫loadUserByUsername(String username)方法
代碼如下:(在此方法中可以執行需要的邏輯)
@Service
public class CustomUserDetailsService implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 查詢數據庫...if (user == null) throw new UsernameNotFoundException("用戶不存在");return new User(user.getUsername(), user.getPassword(), getAuthorities());}
}
(3)登錄完成之后處理(成功、失敗、異常)
以上是我配置的參數
官網文檔:身份驗證事件 :: Spring Security
根據返回的信息,分別處理不同的事件
四:總結
使用Spring Security 框架,可以不需要寫 Controller層的 /login,Spring Security?自動幫我們處理了很多的安全校驗,希望能夠幫助其他小伙伴看懂這個邏輯