Shiro 管理登入/登出/權限/Session。用戶登出時需清理緩存、關閉連接、釋放資源,防止垃圾數據堆積。
LogoutFilterpreHandle():在登出邏輯前執行清理@Service
public class SystemLogoutFilter extends LogoutFilter {
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = getSubject(request, response);
String redirectUrl = getRedirectUrl(request, response, subject);
try {
// 1. 執行業務清理:清空緩存、關閉連接、刪除臨時文件等
// cleanupCache(); closeConnections(); ...
// 2. Shiro 內建登出:清除 Subject、Session、RememberMe Cookie
subject.logout();
} catch (SessionException e) {
e.printStackTrace();
}
// 3. 重導向到登入頁
issueRedirect(request, response, redirectUrl);
// 返回 false:不繼續執行後續 Filter,直接結束
return false;
}
}
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/b/login" />
<property name="successUrl" value="/b" />
<property name="filters">
<map>
<!-- 註冊自定義登出過濾器 -->
<entry key="logout" value-ref="systemLogoutFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
/b/login = authc
/b/logout = logout
/b/** = user
</value>
</property>
</bean>
| 點 | 說明 |
|---|---|
| @Service | 交由 Spring 容器管理,方便注入其他 Bean (如 CacheManager) |
| preHandle 返回 false | 阻斷 Filter 鏈,避免重複處理;issueRedirect 已完成導向 |
| subject.logout() | Shiro 核心登出:清除 Session、Subject 綁定、刪除 RememberMe Cookie |
| redirectUrl | 可配置登出後導向頁面,預設為 loginUrl |
| filterChainDefinitions | /b/logout = logout 匹配自定義 filter name "logout" |
private void cleanup(Subject subject) {
// 1. 清除業務緩存
cacheManager.getCache("userCache").evict(subject.getPrincipal());
// 2. 關閉資源連接
// dbConnection.close(); redisConnection.close(); ...
// 3. 刪除臨時文件
// tempFileService.deleteByUser(subject.getPrincipal());
// 4. 記錄登出日誌
// auditLogService.logLogout(subject.getPrincipal());
}
preHandle 異常不應阻礙登出流程,建議 try-catch 包裹清理邏輯postHandle (但 LogoutFilter 無此方法,可考慮 AOP 或監聽器)