使用FormAuthenticationFilter中的重要方法實現了表單驗證
阿新 • • 發佈:2019-01-05
FormAuthenticationFilter有一個方法
寫一個子類繼承非override這個方法protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { if (isLoginSubmission(request, response)) { if (log.isTraceEnabled()) { log.trace("Login submission detected. Attempting to execute login."); } return executeLogin(request, response); } else { if (log.isTraceEnabled()) { log.trace("Login page view."); } //allow them to see the login page ;) return true; } } else { if (log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the " + "Authentication url [" + getLoginUrl() + "]"); } saveRequestAndRedirectToLogin(request, response); return false; } }
然後用request.setAttribute("shiroLoginFailure", "randomCodeError");設定錯誤資訊,這樣能夠進行錯誤控制寫一個子類繼承於他 protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { // 校驗驗證碼 // 從session獲取正確的驗證碼 HttpSession session = ((HttpServletRequest)request).getSession(); //頁面輸入的驗證碼 String randomcode = request.getParameter("randomcode"); //從session中取出驗證碼 String validateCode = (String) session.getAttribute("validateCode"); if (randomcode!=null && validateCode!=null) { if (!randomcode.equals(validateCode)) { // randomCodeError表示驗證碼錯誤 request.setAttribute("shiroLoginFailure", "randomCodeError"); //拒絕訪問,不再校驗賬號和密碼 return true; } } return super.onAccessDenied(request, response, mappedValue); } }
第二種錯誤方式
自定義的FormAuthenticationFilter覆蓋父類的onLoginFailure,這個方法能夠獲取到AuthenticationException從而能夠進行錯誤處理
然後在登入失敗中取出message/** * 登入失敗呼叫事件 */ @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; }
* 登入失敗,真正登入的POST請求由Filter完成,shiro認證成功後會自動跳轉到上一個路徑
*/
@RequestMapping(value = "${adminPath}/login")
public String loginFail(HttpServletRequest request, HttpServletResponse response, Model model) {
//判斷在FormAuthenticator中有沒有錯誤,即到這一步已經完成了使用者的認證
// String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
// if(exceptionClassName != null){
// if(UnknownAccountException.class.getName().equals(exceptionClassName)){
// throw new CommonException("賬號不存在");
// }else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)){
// throw new CommonException("使用者名稱或者密碼錯誤");
// }else{
// throw new CommonException("系統未知錯誤");
// }
// }
Principal principal = SysUtils.getPrincipal();
// 如果已經登入,則跳轉到管理首頁
if(principal != null){
return "redirect:" + adminPath;
}
String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
boolean rememberMe = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM);
boolean mobile = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_MOBILE_PARAM);
String exception = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
String message = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM);
if (StringUtils.isBlank(message) || StringUtils.equals(message, "null")) {
message = "使用者或密碼錯誤, 請重試!";
根據message返回前臺頁面即可