第一次學習shiro的時候,並沒有發現很大的問題。但後來在做專案的時候,特別是當訪問的url是iframe的頁面的時候,session又過期了,跳轉到登陸頁,完成登陸操作後,返回了只有iframe的頁面,相當不好看。雖然在shiro裡設定了successUrl,但是沒有起作用。
不明真相的我,debug後跟進去觀察後發現FormAuthenticationFilter成功登陸後,會呼叫它的onLoginSuccess方法,最後會呼叫下面這個實際執行的方法。
WebUtils.redirectToSavedRequest(request, response, getSuccessUrl());
我們來窺一下這個方法實際做了什麼。
public static void redirectToSavedRequest(ServletRequest request, ServletResponse response,
String fallbackUrl)throws IOException { String successUrl = null; boolean contextRelative = true; SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request); if (savedRequest != null &&
savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)){ successUrl = savedRequest.getRequestUrl(); contextRelative = false; } if (successUrl == null) { successUrl = fallbackUrl; } if (successUrl == null) { throw new IllegalStateException("....."); } WebUtils.issueRedirect(request, response, successUrl, null, contextRelative); }
可以看出如果由之前的頁面跳轉到登陸頁的話,savedRequest儲存了原來的地址,這個地址會取代我們設定的successUrl;只有當savedRequest為null的時候,successUrl才會是我們設定的地址。
好了,那我們要怎麼做避免它返回頁面,只返回到我們指定的頁面呢?如果要我選的話,我會選擇繼承FormAuthenticationFilter並重寫父類的方法AuthenticationFilter的issueSuccessRedirect方法,最後差不多就是
@override protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception { WebUtils.issueRedirect(request, response, successUrl, null, true); }
原始碼是我們最好的老師,如果網上找不到答案,可以嘗試一下讀原始碼,這樣可以對框架有一個更好的瞭解,準確運用框架有更好的幫助。