shiro捕捉不到Authoricaton异常进行处理的解决办法

时间:2025-03-16 07:03:57

AuthenticationException 异常时Shiro内部进行抛出的,全局异常捕获器在 Filter 之后执行,不能正常进行补捕获,只能在 Filter内部进行处理。

解决方案:

自定义的realm抛出错误信息:
            /*验证这个账号是否被封号了*/
            if(()==1){
                throw new AuthenticationException("账号已被封禁,请联系管理员");
            }

自定义filter:

        private String errorMsg;//用于接收realm抛出的异常信息“账号已被封禁,请联系管理员”
        private Logger logger = (());

        /**
         * 如果带有 token,则对 token 进行检查,否则直接通过
         */
        @Override
        protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {
            //判断请求的请求头是否带上 "Token"用到了isLoginAttempt
            if (isLoginAttempt(request, response)) {
                //如果存在,则进入 executeLogin 方法执行登入,检查 token 是否正确
                try {
                    executeLogin(request, response);
                } catch (Exception e) {
                    //token 错误
                    errorMsg=();
                    return false ;/*别漏了这个只有返回false才会进入 onAccessDenied 方法进而返回json格式错误信息给前端*/
                }
            }
            //如果请求头不存在 Token,则可能是执行登陆操作或者是游客状态访问,无需检查 token,直接返回 true
            ("请求头token为空返回true");
            return true;
        }

如果上述方法抛出异常并且return false后会进入下面这个方法:

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        (200);
        ("application/json;charset=utf-8");
        JSONObject json = new JSONObject();
        if("账号已被封禁,请联系管理员".equals(errorMsg)){
            ("status",202);
            ("msg","账号已被封禁,请联系管理员");
        }else{ ("status",402);
            ("msg","凭证失效或已过期,请重新登陆!");}
        PrintWriter out = ();
        (json);
        ();
        ();
        return false;//返回false拒绝访问会直接返回错误信息
    }