1. 程式人生 > >使用FormAuthenticationFilter中的重要方法實現了表單驗證

使用FormAuthenticationFilter中的重要方法實現了表單驗證

FormAuthenticationFilter有一個方法

    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;
        }
    }
寫一個子類繼承非override這個方法
寫一個子類繼承於他
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);
	}
}
然後用request.setAttribute("shiroLoginFailure", "randomCodeError");設定錯誤資訊,這樣能夠進行錯誤控制

第二種錯誤方式

自定義的FormAuthenticationFilter覆蓋父類的onLoginFailure,這個方法能夠獲取到AuthenticationException從而能夠進行錯誤處理

	/**
	 * 登入失敗呼叫事件
	 */
	@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;
	}
然後在登入失敗中取出message
	 * 登入失敗,真正登入的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返回前臺頁面即可