使用FormAuthenticationFilter中的重要方法实现了表单验证

来源:互联网 发布:安全阀计算软件 编辑:程序博客网 时间:2024/06/06 07:01

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从而能够进行错误处理

/** * 登录失败调用事件 */@Overrideprotected 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返回前台页面即可




0 0