| 策略 | 適用場景 |
| MODE_THREADLOCAL | 預設,每請求一線程,Web 應用標準 |
| MODE_INHERITABLETHREADLOCAL | 子線程繼承父線程 Context,異步處理需謹慎 |
| MODE_GLOBAL | 單一 JVM 全域共享,僅測試/單執行緒應用 |
同步問題:HttpSession 與 SecurityContextHolder 雙重存放,HttpSessionContextIntegrationFilter 負責雙向同步。
4. 常見 Filter 擴充點
logoutFilter:登出處理
securityContextHolderAwareRequestFilter:Request 包裝
anonymousProcessingFilter:匿名認證
5. 防止重複執行
if (request.getAttribute(FILTER_APPLIED) != null) {
chain.doFilter(request, response);
return;
}
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
防止同一 Filter 在 RequestDispatcher forward/include 時重複執行。
6. getSession(boolean) 異常處理
try {
httpSession = request.getSession(forceEagerSessionCreation);
} catch (IllegalStateException ignored) {
// 響應已提交無法建立 Session,靜默忽略
}
避免「Response Committed」後建立 Session 拋出 IllegalStateException。
7. OnRedirectUpdateSessionResponseWrapper
包裝 HttpServletResponse,攔截 sendRedirect(),確保 Session ID 在重導向 URL 中正確編碼 (URL Rewriting),支援無 Cookie 環境。
8. SecurityContextHolder.clearContext() 必要性
每請求結束清理 ThreadLocal,防止:
- 線程池複用導致身份洩漏。
- 權限變更 (如管理員撤銷用戶權限) 未即時生效。
9. Context Clone 機制
if (cloneFromHttpSession) {
// 反射呼叫 clone(),確保可存取
Method m = clazz.getMethod("clone");
if (!m.isAccessible()) m.setAccessible(true);
context = m.invoke(contextFromSession);
}
避免直接返回 Session 中的 Context 物件,防止呼叫端修改導致「髒檢查」失效或並發問題。參考 Hibernate PersistentContext 設計。
10. readSecurityContextFromSession 防禦性編程
- 層層檢查:非 null、型別正確、Key 存在、實作
SecurityContext 介面。
- 詳細除錯日誌:
log.debug("Obtained from Session: " + context),便於追蹤。
- 上一篇文章: Acegi LogoutFilter 配置詳解與常見問題探討
- 下一篇文章: Acegi 七劍下天山:核心組件與請求處理流程圖解
Copyright ©
程式碼之家 All Rights Reserved