問題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。