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拒绝访问会直接返回错误信息
}