LogoutFilter 處理登出邏輯:清除 SecurityContext、失效 Session、導向登出成功頁。配置簡單但有幾個細節值得深究。
一、標準配置
<bean id="logoutFilter"
class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/login.jsp"/> <!-- 登出後導向 -->
<constructor-arg>
<list>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<!-- Filter 鏈 -->
/**=httpSessionContextIntegrationFilter,
logoutFilter,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterInvocationInterceptor
二、JSP 登出連結
<a href="/myOwnAcegi/j_acegi_logout">退出</a>
j_aceci_logout 為固定 URL,由 LogoutFilter 攔截處理。
三、構造函式參數解析
| 參數 | 類型 | 說明 |
| 1 | String | logoutSuccessUrl,登出後重導向頁面 |
| 2 | LogoutHandler[] | 登出處理器陣列,Spring <list> 自動轉型 |
SecurityContextLogoutHandler 執行:SecurityContextHolder.clearContext()、request.getSession().invalidate()、Cookie 清理。
四、優化:獨立登出 Filter 鏈
/j_acegi_logout=httpSessionContextIntegrationFilter,logoutFilter
優點:登出請求不再通過後續 3 個 Filter,減少無謂處理。
缺點:需確保 httpSessionContextIntegrationFilter 仍在鏈中(提供 Session 存取),否則 SecurityContextLogoutHandler 可能失效。
五、原始碼關鍵邏輯
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
if (requiresLogout(request, response)) {
for (LogoutHandler handler : handlers) {
handler.logout(request, response, SecurityContextHolder.getContext().getAuthentication());
}
sendRedirect(request, response, logoutSuccessUrl); // 核心導向
return;
}
chain.doFilter(request, response);
}
六、常見問題
- Spring List 轉陣列:
<constructor-arg><list><bean .../></list></constructor-arg>,Spring 利用 List.toArray() 自動轉型。
- 重複登出:Filter 內部
requiresLogout 判斷請求路徑是否為 j_acegi_logout,避免誤觸發。
- Session 失效時機:若
httpSessionContextIntegrationFilter 在 logoutFilter 之後,Session 可能已被提交導致 invalidate() 失效,建議保持順序。
- 上一篇文章: Acegi SecurityContextHolderAwareRequestFilter 核心原理與三大方法覆寫
- 下一篇文章: Acegi 源碼研究筆記:設計細節與編碼智慧
Copyright ©
程式碼之家 All Rights Reserved