前述
在项目中使用Springboot 2.1.2.RELEASE整合shiro进行token认证时,在只装配了单个Realm的情况下执行验证,无法抛出自定义异常。
Filter的代码
public class JwtFilter extends BasicHttpAuthenticationFilter {
......
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
String token = getAuthzHeader(request);
if (StrUtil.isNotEmpty(token)) {
WxToken wxToken = new WxToken(token);
getSubject(request, response).login(wxToken);
return true;
}
return false;
}
}
单个Realm的代码
public class WxUserRealm extends AuthorizingRealm {
@Autowired
RedisUtil redisUtil;
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof WxToken;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
String wxToken = (String) token.getCredentials();
Claims claims = JwtUtil.parseToken(wxToken);
if (claims != null) {
String cacheToken;
cacheToken = redisUtil.get("jwtId-" + claims.get("id"));
if (cacheToken != null) {
return new SimpleAuthenticationInfo(cacheToken, cacheToken, getName());
} else {
throw new MyException("token过期!");
}
} else {
throw new MyException("非法token");
}
}
......
}
全局异常处理
@Slf4j
@Controller
@RestControllerAdvice
public class GlobalExceptionHandler implements ErrorController {
......
@ExceptionHandler(value = MyException.class)
public JsonResponse myException(MyException e) {
log.error(ThrowableUtil.getStackTrace(e));
return new JsonResponse(e.getStatus(), e.getMessage(), null);
}
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping(value = {"/error"})
public JsonResponse error() {
JsonResponse jr = new JsonResponse();
jr.setCodeAndMsg(HttpStatus.NOT_FOUND);
return jr;
}
}
运行程序
自定义异常即将被抛出
运行至全局异常处理类
JSON格式响应
自定义的异常只在控制台打印
更换shiro内置异常抛出
public class WxUserRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
String wxToken = (String) token.getCredentials();
Claims claims = JwtUtil.parseToken(wxToken);
if (claims != null) {
String cacheToken;
cacheToken = redisUtil.get("jwtId-" + claims.get("id"));
if (cacheToken != null) {
return new SimpleAuthenticationInfo(cacheToken, cacheToken, getName());
} else {
throw new ExpiredCredentialsException();
}
} else {
throw new UnsupportedTokenException();
}
}
......
}
全局异常处理中加入
@ExceptionHandler(value = UnsupportedTokenException.class)
public String UnsupportedTokenException(HttpServletRequest request, HttpServletResponse response, Exception exception) {
JsonResponse jr = new JsonResponse();
jr.setCodeAndMsg(HttpStatus.FORBIDDEN);
return jr;
}
运行程序
内置异常即将被抛出
运行至全局异常处理类
JSON格式响应
异常仍被打印至控制台
修改error接口
@RequestMapping(value = {"/error"})
public JsonResponse error(HttpServletRequest request, HttpServletResponse response) {
JsonResponse jr = new JsonResponse();
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
Throwable cause = exception.getCause();
if (cause instanceof UnsupportedTokenException) {
jr.setCodeAndMsg(ExceptionEnum.TOKEN_ILLEGAL);
} else if (cause instanceof ExpiredCredentialsException) {
jr.setCodeAndMsg(ExceptionEnum.TOKEN_EXPIRED);
} else {
jr.setCodeAndMsg(HttpStatus.NOT_FOUND);
}
return jr;
}
运行程序
再次运行并抛出内置异常,被Controller成功识别
自定义异常抛出成功










网友评论