Spring Security 捕获 filter层面异常,请问如何才能捕获到filter里的异常自己处理呢?

image.png

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Resource
    public RedisCache redisCache;



    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取token
        String token = request.getHeader("token");

        if (!StringUtils.hasText(token)) {
            //放行
            filterChain.doFilter(request, response);
            return;
        }
        //解析token
        String userid;
        try {
            Claims claims = JwtUtils.parseJWT(token);
            if(JwtUtils.isTokenExpired(claims)){
                throw new CustomException(CustomExceptionType.NEED_LOGIN,"token过期");
            }
            userid = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(CustomExceptionType.NEED_LOGIN,"登录信息过期,请重新登录");
        }

        //从redis中获取用户信息
        SysUser user = redisCache.getCacheObject("login:" + userid);
        List<String> permissions = redisCache.getCacheObject("permissions:"+userid);
        if(Objects.isNull(user)){
//            throw new CustomException(CustomExceptionType.NEED_LOGIN,"登录信息过期,请重新登录");
            return;
        }
        LoginUser loginUser = new LoginUser(user,permissions);

        ThreadLocalUtils.setUser(user);
        //存入SecurityContextHolder
        //TODO 获取权限信息封装到Authentication中
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        filterChain.doFilter(request, response);
    }
}

当我想用 一个过滤器(OncePerRequestFilter)来对所有请求进行jwt校验,当校验不通过时我想抛出异常,然后再通过@ExceptionHandler来全局捕获该异常,发现SpringBoot 全局异常捕获不了filter中抛出的异常,导致返回的格式就和上面的截图一样

尝试了使用response 直接把要返回的内容写进入 也是没效果
我尝试使用了BasicErrorController 但是也没能拦截到

import com.szhb.backend.exception.CustomException;
import com.szhb.backend.exception.CustomExceptionType;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;


@RestController
@ApiIgnore
public class FilterErrorController extends BasicErrorController {

    public FilterErrorController() {
        super(new DefaultErrorAttributes(), new ErrorProperties());
    }

    @Override
    @RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity error(HttpServletRequest request) {
        throw new CustomException(CustomExceptionType.USER_INPUT_ERROR,"需要登录");
    }



}
阅读 3.8k
1 个回答

spring security有专门的异常处理filter,直接就在filter这一层面就处理了,都走不到servlet来,dispatchservlet都都不到它这里来

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进