出自:http://www.cnblogs.com/sevenlin/p/sevenlin_shiro20150924.html
通常我們使用shiro,登錄之后就會跳到我們上一次訪問的URL,如果我們是直接訪問登錄頁面的話,shiro就會根據我們配置的successUrl去重定向,如果我們沒有配置successUrl的話,那么shiro重定向默認的/,這個邏輯看shiro的源碼就可以知道:
1.shiro會把請求信息保存到session中:
2.然后判斷是否已經登錄,如果沒有登錄,就會跳到登錄頁面,用戶輸入憑證之后就會交給FormAuthenticationFilter這個類來處理;
3.如果登錄成功之后就會調用一下方法重定向:
其中的issueSuccessRedirect方法如下:
FormAuthenticationFilter出來之后就會交給這個方法處理重定向:
從上面就可以看出,shiro去session中找出之前的保存的請求,如果沒有的話就會跳轉到我們配置的successUrl!
但是現實中往往有很多需求就是,要求我們登錄成功之后要跳到一個固定的頁面,通常是跳到首頁,那這時候我們應該怎么做呢?
通過查看源碼,我發現在shiro的webUtils工具類中有這樣一個方法:
意思是,獲取session中的請求信息,並且清理他;
有了這個方法之后就好辦了!
我們可以重寫FormAuthenticationFilter的onLoginSuccess方法,具體如下:
public class MyFormAuthenticationFilter extends FormAuthenticationFilter{ private Logger logger = LoggerFactory.getLogger(CaptchaFormAuthenticationFilter.class); public static final String DEFAULT_CAPTCHA_PARAM = "captcha"; private String captchaParam = DEFAULT_CAPTCHA_PARAM; public String getCaptchaParam() { return captchaParam; } protected String getCaptcha(ServletRequest request) { return WebUtils.getCleanParam(request, getCaptchaParam()); } @Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) { String captcha = getCaptcha(request); String username = getUsername(request); String password = getPassword(request); boolean rememberMe = isRememberMe(request); String host = getHost(request); if(true){ try{ password =SecurityUtil.get().decrypt(password, SecurityUtil.get().getPublicArrayKey()).trim();//前端密碼js解密 logger.debug("密碼js解密成功!"); }catch(Exception e){ logger.error("用戶為"+username+"的密碼js解密失敗!", e); } } CaptchaUsernamePasswordToken authenticationToken= new CaptchaUsernamePasswordToken(username, password, rememberMe, host, captcha,(HttpServletRequest) request); return authenticationToken; } /** * 思路:用戶輸入憑證之后就會交給FormAuthenticationFilter這個類來處理,如果登錄成功之后就會調用onLoginSuccess()方法重定向, * 最后調用WebUtils.redirectToSavedRequest()方法,該方法中可以看出shiro去session中找出之前的保存的請求, * 如果沒有的話就會跳轉到我們配置的successUrl。 * 解決辦法:用戶回話過期后,重新登錄后會訪問session保存的訪問地址造成頁面布局混亂,這里直接清除之前保存的session中保存的請求信息,並且清理它 */ @Override protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { WebUtils.getAndClearSavedRequest(request);//清除之前的地址(跳轉到登錄頁面之前要訪問的地址) return super.onLoginSuccess(token, subject, request, response); } }
這樣,就實現了在交給shiro處理重定向的時候清理了session中保存的請求信息,這樣的話,就可以我們指定的url傳遞進去,這樣就實現了跳轉到我們指定的頁面;
其次,要把我們定義的過濾器配置一下:
注入:
加到shiro過濾器鏈中:
這樣使用authc的時候就是我們自定一個過濾器了,如果覺得用同個名字不好也可以自己定義名字!