首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Acegi 源碼研究筆記:設計細節與編碼智慧

     編輯:Java 相關知識

閱讀 Acegi (Spring Security 2.x) 核心原始碼時的碎片筆記,記錄關鍵設計決策與工程智慧,供架構參考。

1. FilterToBeanProxy → FilterChainProxy

  • web.xml 配置標準 Servlet Filter:FilterToBeanProxy。
  • 委派給 Spring 容器中的 FilterChainProxy (實作 Filter),實現「Spring 管理 Filter 生命週期」。
  • VirtualFilterChain 模擬容器 FilterChain,支援動態鏈路。

2. filterInvocationDefinitionSource 字串自動轉型

FilterChainProxy.setFilterInvocationDefinitionSource(String) 接收多行字串,內部委派 PathBasedFilterInvocationDefinitionMap 解析 Ant 路徑模式,轉為 FilterInvocationDefinitionSource 介面實現。展示 Spring PropertyEditor 強大的類型轉換體系。

3. SecurityContextHolder 多策略實現

同步問題: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),便於追蹤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
策略適用場景
MODE_THREADLOCAL預設,每請求一線程,Web 應用標準
MODE_INHERITABLETHREADLOCAL子線程繼承父線程 Context,異步處理需謹慎
MODE_GLOBAL單一 JVM 全域共享,僅測試/單執行緒應用