第一次學習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); }
源碼是我們最好的老師,如果網上找不到答案,可以嘗試一下讀源代碼,這樣可以對框架有一個更好的了解,准確運用框架有更好的幫助。