java鬼混筆記:shiro 11、唯一登入和登入退出Bug
阿新 • • 發佈:2019-02-13
完整的專案下載路徑(專案下載網上的hui框架來著,什麼鬼檔案都在裡面,暫清除,所以很多):
http://download.csdn.net/download/u013845177/9992748
相關的lib包路徑:
http://download.csdn.net/download/u013845177/9992728
這次的筆記是在執行程式時,發現一個問題,今天才有空處理。問題舉例來講吧:比如使用者A第1次登入後,由於設定了唯一登入,用了Deque儲存使用者的sessionId,當用戶A退出時, session是清空了,但是Deque中沒有清空。第二次A再次登入,這時Deque又把sessionid放進去,這時Deque中sessionid 有兩個,由於設定了唯一登入,這時要清空第1次登入的sessionid對應的session,但是第1次sessionid清空了,找不到了,所以報了session找不到,控制檯紅紅的。。。
解決方案:自定義一個退出類,手動清空Deque。上程式碼...
package cn.common;
import java.io.Serializable;
import java.util.Deque;
import java.util.LinkedList;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import cn.entity.User;
public class LSLogoutFilter extends LogoutFilter {
private Cache<String, Deque<Serializable>> cache;
private CacheManager cacheManager;
public CacheManager getCacheManager() {
return cacheManager;
}
public void setCacheManager(CacheManager cacheManager) {
this.cache = cacheManager.getCache("shiro-kickout-session");
}
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = getSubject(request, response);
String redirectUrl = getRedirectUrl(request, response, subject);
try {
// 獲取退出使用者的資訊
User user = (User) subject.getPrincipal();
LinkedList ll = (LinkedList) cache.get(user.getUserName());// 找到這個使用者在快取中的Deque
if(ll != null) {
ll.removeLast();// 根據LinkedList機制,清空最後一個sessionid
}
cache.put(user.getUserName(), ll);// 放回去
subject.logout();
} catch (SessionException ise) {
ise.printStackTrace();
}
issueRedirect(request, response, redirectUrl);
return false;
}
}
接著在applicationContext-shiro.xml加入這個bean
<!-- 自定義退出功能 -->
<bean id="lSLogoutFilter" class="cn.common.LSLogoutFilter">
<property name="cacheManager" ref="cacheManager"/>
</bean>
同時在<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">中加入紅色的程式碼:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="filters">
<map>
<entry key="authc" value-ref="LSFormAuthenticationFilter" /><!-- 配置自定義的form過濾器 -->
<entry key="kickout" value-ref="kickoutSessionControlFilter"/><!-- 踢人 -->
<entry key="logout" value-ref="lSLogoutFilter"/><!-- 退出 -->
</map>
</property>
<!-- 沒有登入就跳到這 -->
<property name="loginUrl" value="/login.do" />
<!-- successUrl認證成功後跳轉的url,去掉,因為實際中,比如successUrl對應的是A頁,
我在訪問C頁面時,有一個功能是要登入才可以操作的,如果我配置了successUrl,那麼我登入成功之後會跳轉A頁面,然後我再各種點點點才回到C頁面,
這就很蛋疼了,如果我沒配置 successUrl,那麼在登入之後,shiro會自動跳轉到上一個url,也是登入頁面前一個url,那就是C頁面的url,也就是C頁面跳轉到登入頁面後,成功登入後直接返回到C頁面,我就可以繼續在C頁面做事了-->
<!-- <property name="successUrl" value="index.do"/> -->
<property name="filterChainDefinitions">
<value>
/ssiupload/** = anon
/up.jsp = anon
<!-- logout.do shiro自己清空session -->
/logout.do = logout<!-- 注意這裡引用退出-->
OK。。。