/** 重写父类方法,当登录失败次数大于allowLoginNum(允许登录次)时,将显示验证码 */ @Override protected boolean onLoginFailure( AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { if (e instanceof CaptchaValidationException) { request.setAttribute(KEY_AUTH_CAPTCHA_REQUIRED, Boolean.TRUE); } else if (e instanceof IncorrectCredentialsException) { // 消息友好提示 e = new IncorrectCredentialsException("登录账号或密码不正确"); // 失败记录 SourceUsernamePasswordToken sourceUsernamePasswordToken = (SourceUsernamePasswordToken) token; User authAccount = userService.findByAuthTypeAndAuthUid( User.AuthTypeEnum.SYS, sourceUsernamePasswordToken.getUsername()); if (authAccount != null) { authAccount.setLogonTimes(authAccount.getLogonTimes() + 1); authAccount.setLastLogonFailureTime(DateUtils.currentDate()); authAccount.setLogonFailureTimes(authAccount.getLogonFailureTimes() + 1); userService.save(authAccount); // 达到验证失败次数限制,传递标志属性,登录界面显示验证码输入 if (authAccount.getLogonFailureTimes() > LOGON_FAILURE_LIMIT) { request.setAttribute(KEY_AUTH_CAPTCHA_REQUIRED, Boolean.TRUE); } } } return super.onLoginFailure(token, e, request, response); }
@Override protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { SourceUsernamePasswordToken token = (SourceUsernamePasswordToken) createToken(request, response); try { String username = getUsername(request); // 写入登录账号名称用于回显 request.setAttribute(KEY_AUTH_USERNAME_VALUE, username); User authAccount = userService.findByAuthTypeAndAuthUid(User.AuthTypeEnum.SYS, username); if (authAccount != null) { // 失败LOGON_FAILURE_LIMIT次,强制要求验证码验证 if (authAccount.getLogonFailureTimes() > LOGON_FAILURE_LIMIT) { String captcha = request.getParameter(captchaParam); if (StringUtils.isBlank(captcha) || !ImageCaptchaServlet.validateResponse((HttpServletRequest) request, captcha)) { throw new CaptchaValidationException("验证码不正确"); } } Subject subject = getSubject(request, response); subject.login(token); return onLoginSuccess(token, subject, request, response); } else { return onLoginFailure(token, new UnknownAccountException("登录账号或密码不正确"), request, response); } } catch (AuthenticationException e) { return onLoginFailure(token, e, request, response); } }
/** 重写父类方法,当登录成功后,重置失败标志 */ @Override protected boolean onLoginSuccess( AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpServletResponse = (HttpServletResponse) response; HttpServletRequest httpServletRequest = (HttpServletRequest) request; SourceUsernamePasswordToken sourceUsernamePasswordToken = (SourceUsernamePasswordToken) token; User authAccount = userService.findByAuthTypeAndAuthUid( User.AuthTypeEnum.SYS, sourceUsernamePasswordToken.getUsername()); Date now = DateUtils.currentDate(); // 更新Access Token,并设置半年后过期 if (StringUtils.isBlank(authAccount.getAccessToken()) || authAccount.getAccessTokenExpireTime().before(now)) { authAccount.setAccessToken(UUID.randomUUID().toString()); authAccount.setAccessTokenExpireTime( new DateTime(DateUtils.currentDate()).plusMonths(6).toDate()); userService.save(authAccount); } // 写入登入记录信息 UserLogonLog userLogonLog = new UserLogonLog(); userLogonLog.setLogonTime(DateUtils.currentDate()); userLogonLog.setLogonYearMonthDay(DateUtils.formatDate(userLogonLog.getLogoutTime())); userLogonLog.setRemoteAddr(httpServletRequest.getRemoteAddr()); userLogonLog.setRemoteHost(httpServletRequest.getRemoteHost()); userLogonLog.setRemotePort(httpServletRequest.getRemotePort()); userLogonLog.setLocalAddr(httpServletRequest.getLocalAddr()); userLogonLog.setLocalName(httpServletRequest.getLocalName()); userLogonLog.setLocalPort(httpServletRequest.getLocalPort()); userLogonLog.setServerIP(IPAddrFetcher.getGuessUniqueIP()); userLogonLog.setHttpSessionId(httpServletRequest.getSession().getId()); userLogonLog.setUserAgent(httpServletRequest.getHeader("User-Agent")); userLogonLog.setXforwardFor(IPAddrFetcher.getRemoteIpAddress(httpServletRequest)); userLogonLog.setAuthType(authAccount.getAuthType()); userLogonLog.setAuthUid(authAccount.getAuthUid()); userLogonLog.setAuthGuid(authAccount.getAuthGuid()); userService.userLogonLog(authAccount, userLogonLog); if (isMobileAppAccess(request)) { return true; } else { // 根据不同登录类型转向不同成功界面 AuthUserDetails authUserDetails = AuthContextHolder.getAuthUserDetails(); // 判断密码是否已到期,如果是则转向密码修改界面 Date credentialsExpireTime = authAccount.getCredentialsExpireTime(); if (credentialsExpireTime != null && credentialsExpireTime.before(DateUtils.currentDate())) { httpServletResponse.sendRedirect( httpServletRequest.getContextPath() + authUserDetails.getUrlPrefixBySource() + "/profile/credentials-expire"); return false; } // 如果是强制转向指定successUrl则清空SavedRequest if (forceSuccessUrl) { WebUtils.getAndClearSavedRequest(httpServletRequest); } return super.onLoginSuccess(token, subject, request, httpServletResponse); } }