Apache Shiro會話超時,登錄頁面跳轉到父窗體的解決方法

問題1:

在使用Apache Shiro框架做權限驗證時,因爲我的頁面是使用iframe做了一個上左右的分層,上面上log,左側是菜單,具體的內容則顯示在右側。

當我點擊某菜單,此時如果會話超時了,則登錄頁面只會顯示到右側區域,看起來不是很友好,所以需要登錄頁面顯示到整個瀏覽器。


解決方法:

在登錄頁面做一個跳轉,當登錄頁面不是在頂層顯示,則跳轉:

window.onload = function () {
	    if (window.parent.window != window) {
	        window.top.location = "/login-main.action";
	    }
	}

問題2:

因爲Shiro會記錄上一次造成會話超時的頁面,登錄成功後,會直接跳轉到這個頁面,而我這裏是層級顯示,所以,如果使用Shiro的跳轉,則跳轉的頁面,將沒有log和菜單欄了


解決方法:

1、重寫登錄的過濾器,將Shiro記錄的頁面清除並保存到自己定義的session中,完成跳轉。

2、在首頁,將自定義保存的請求取出跳轉。

過濾器:

package cn.zfcr.shiro.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service;

/** 
    文件名:FormAuthenticationFilter.java
    類說明:  Shiro 表單驗證過濾器擴展 寫入登錄驗證失敗的錯誤提示
    作者:章鋒
    郵箱: [email protected]
    日期:2017年6月22日 下午2:29:54  
    描述:例:章鋒-認證
    版本:1.0
*/
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
    
    public static final String DEFAULT_MESSAGE_PARAM = "message";
    
    /** 自定義保存到session中的請求數據的key 用於頁面跳轉 */
    public static final String CUSTOM_SAVED_REQUEST = "customSavedRequest";
    
    private String messageParam = DEFAULT_MESSAGE_PARAM;
    
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
            ServletResponse response) throws Exception {
        SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
        Session session = subject.getSession();
        session.setAttribute(CUSTOM_SAVED_REQUEST, savedRequest);
        return super.onLoginSuccess(token, subject, request, response);
    }

	/**
	 * 登錄失敗調用事件
	 */
	@Override
	protected boolean onLoginFailure(AuthenticationToken token,
			AuthenticationException e, ServletRequest request, ServletResponse response) {
		String className = e.getClass().getName(), message = "";
		if (IncorrectCredentialsException.class.getName().equals(className)
				|| UnknownAccountException.class.getName().equals(className)){
			message = "用戶名或密碼錯誤, 請重試.";
		}
		else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
			message = StringUtils.replace(e.getMessage(), "msg:", "");
		}
		else{
			message = "系統異常,請稍後再試!";
			e.printStackTrace();
		}
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(getMessageParam(), message);
        return true;
	}
	
	public String getMessageParam() {
        return messageParam;
    }
}

首頁跳轉代碼:

<s:if test="#session.customSavedRequest != null">
    <script type="text/javascript">
        var url = '${session.customSavedRequest.requestURI}?${session.customSavedRequest.queryString}';
        $("#mainFrame").attr("src", url);
    </script>
</s:if>

ok。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章