?? 漫畫SpringSecurity - 守護應用安全的鋼鐵衛士
?? 目錄
- 記憶口訣
- 可視化圖表
- 形象比喻
- 數字記憶
- 實戰案例
- 記憶卡片
- 總結詩句
- 面試準備
?? 記憶口訣
??? SpringSecurity核心 - “認證授權過濾鏈”
認證Authentication確身份,用戶名密碼驗證真
授權Authorization控權限,角色資源細粒度
過濾器鏈FilterChain,請求層層來過濾
SecurityContext上下文,當前用戶信息存
UserDetails用戶詳情,權限角色全包含
?? OAuth2四種模式 - “授權碼密碼憑證客戶端”
授權碼模式最安全,第三方登錄常用它
密碼模式信任度高,自家應用可以用
客戶端憑證服務器,后臺API認證佳
簡化模式已過時,安全風險不推薦
?? JWT令牌結構 - “頭部載荷簽名三段式”
Header頭部算法聲明,typ和alg要指定
Payload載荷存信息,用戶權限過期時間
Signature簽名防篡改,密鑰加密保安全
三段Base64用點連,無狀態認證很方便
?? 安全配置要點 - “配置方法安全傳輸”
configure配置核心,HttpSecurity要定制
anyRequest所有請求,permitAll允許通過
hasRole角色驗證,hasAuthority權限細
CSRF跨站防護,同源策略要開啟
HTTPS傳輸加密,敏感數據不泄露
?? 可視化圖表
??? SpringSecurity架構全景圖
┌─────────────────────────────────────────────────────────────┐
│ Web應用層 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Controller │ │ Service │ │ DAO │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────┬────────────────────────────────────────┘│
┌──────────────────▼────────────────────────────────────────┐
│ SpringSecurity過濾器鏈 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │SecurityContextPersistenceFilter│ │LogoutFilter │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │UsernamePasswordAuthenticationFilter││ExceptionTranslationFilter│
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ │
│ │FilterSecurityInterceptor│ │
│ └─────────────┘ │
└──────────────────┬────────────────────────────────────────┘│
┌──────────────────▼────────────────────────────────────────┐
│ 認證授權管理器 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │AuthenticationManager│ │AccessDecisionManager│ │UserDetailsService│
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────┬────────────────────────────────────────┘│
┌──────────────────▼────────────────────────────────────────┐
│ 數據存儲層 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 數據庫 │ │ Redis │ │ LDAP │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
?? 認證授權流程圖
用戶請求 → SecurityFilterChain → 認證檢查↓ ↓ ↓
未認證 已認證但無權限 認證且有權限↓ ↓ ↓
跳轉登錄頁 返回403錯誤 繼續處理請求↓
用戶登錄 → AuthenticationManager → UserDetailsService↓ ↓ ↓
登錄成功 登錄失敗 查詢用戶信息↓ ↓ ↓
創建認證對象 返回錯誤信息 返回UserDetails↓
存儲到SecurityContext → 訪問受保護資源
?? OAuth2授權碼模式流程圖
客戶端 → 授權服務器 → 用戶同意 → 返回授權碼↓ ↓ ↓ ↓
用授權碼 → 交換令牌 → 驗證通過 → 返回訪問令牌↓ ↓ ↓ ↓
攜帶令牌 → 資源服務器 → 驗證令牌 → 返回資源
?? 形象比喻
?? "城堡守衛"比喻
SpringSecurity就像一座戒備森嚴的城堡:
- 城墻(SecurityFilterChain): 多層防護,每一層都有特定職責
- 守衛(AuthenticationManager): 驗證來訪者身份的衛兵隊長
- 門禁卡(Authentication): 證明身份的通行證
- 權限徽章(Authority): 不同區域的訪問權限標識
- 訪客登記(UserDetailsService): 查詢訪客信息的檔案系統
- 安全令牌(JWT): 臨時通行證,有時效性
?? "銀行安保"比喻
OAuth2就像銀行的多重安全驗證:
- 大廳接待(Authorization Server): 負責身份驗證的前臺
- 安保主管(Resource Server): 保護貴重物品的金庫
- 客戶經理(Client): 代表客戶辦理業務的第三方
- 授權書(Authorization Code): 臨時的業務授權憑證
- 銀行卡(Access Token): 正式的訪問憑證
- 密碼器(Refresh Token): 更新訪問憑證的設備
?? "劇院檢票"比喻
JWT認證就像劇院的電子門票:
- 門票信息(Header): 票據類型和加密方式
- 觀眾信息(Payload): 座位號、有效期、觀眾身份
- 防偽標識(Signature): 防止門票被偽造的數字簽名
- 檢票口(Filter): 驗證門票真偽的關卡
- 入場后(SecurityContext): 獲得觀看演出的權限
?? 數字記憶
?? SpringSecurity重要數字
- 默認端口: 無固定端口,依托Web應用
- 過濾器數量: 15+個核心過濾器
- OAuth2模式: 4種授權模式
- JWT段數: 3段 (Header.Payload.Signature)
- 默認會話超時: 30分鐘
- 密碼強度: 最少8位,包含大小寫數字特殊字符
?? 安全配置數據
密碼加密強度:
- BCrypt: 10輪加密 (推薦)
- SCrypt: 內存開銷大,更安全
- Argon2: 最新算法,抗側信道攻擊令牌有效期:
- Access Token: 15分鐘-2小時
- Refresh Token: 7-30天
- Remember Me: 2周會話管理:
- 最大并發會話: 1-3個
- 會話固化攻擊防護: 默認開啟
- 會話超時檢測: 5分鐘間隔
?? 性能基準數據
認證性能 (QPS):
- 基于Session: ~5000
- 基于JWT: ~10000
- 基于Redis: ~8000加密算法性能:
- MD5: 已廢棄,不安全
- SHA-256: 快速但不適合密碼
- BCrypt: 慢但安全,適合密碼
- SCrypt: 更慢更安全
?? 實戰案例
?? 企業級權限管理系統
場景描述
構建一個支持多租戶的企業權限管理系統,要求:
- 支持RBAC權限模型
- 集成第三方OAuth2登錄
- JWT無狀態認證
- 細粒度權限控制
- 支持單點登錄SSO
核心技術實現
1. 安全配置和過濾器鏈
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {@Autowiredprivate JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;@Autowiredprivate JwtAuthenticationFilter jwtAuthenticationFilter;@Autowiredprivate CustomUserDetailsService userDetailsService;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(12);}@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {return config.getAuthenticationManager();}@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.csrf(csrf -> csrf.disable()).sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)).authorizeHttpRequests(auth -> auth.requestMatchers("/api/auth/**", "/api/public/**").permitAll().requestMatchers(HttpMethod.GET, "/api/products/**").hasAnyRole("USER", "ADMIN").requestMatchers("/api/admin/**").hasRole("ADMIN").requestMatchers("/api/manager/**").hasAnyAuthority("MANAGE_USERS", "MANAGE_PRODUCTS").anyRequest().authenticated()).exceptionHandling(ex -> ex.authenticationEntryPoint(jwtAuthenticationEntryPoint)).addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);return http.build();}
}
2. JWT認證實現
@Component
@Slf4j
public class JwtTokenProvider {@Value("${app.jwt.secret}")private String jwtSecret;@Value("${app.jwt.expiration}")private int jwtExpirationInMs;public String generateToken(Authentication authentication) {UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(