springboot整合springsecurity无法捕获自定义异常
记录一次自己遇到的问题
目的:验证token,异常返回自定义内容。
@RestControllerAdvice只能拦截controller层的异常,然而filter异常是在controller之前,所以当我想要验证token出现自定义异常时,直接返回
解决方法,直接在过滤器中返回响应体response自定义的内容
public class HttpContextUtil {
public HttpContextUtil() {
}
public static HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return requestAttributes == null ? null : requestAttributes.getRequest();
}
public static HttpServletResponse getResponse() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
return requestAttributes == null ? null : requestAttributes.getResponse();
}
}
public static void error(HttpStatus status, ErrorResult errorResult) {
HttpServletResponse response = HttpContextUtil.getResponse();
if (response != null && !response.isCommitted()) {
response.setContentType("application/json;charset=utf-8");
response.setStatus(status.value());
try {
response.getWriter().write( JSONUtil.toJsonStr(Result.error(errorResult));
} catch (IOException ignored) {
}
}
}
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
RedisCache redisCache;
@Autowired
TokenService tokenService;
private static final String TOKEN = "TOKEN";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
//验证token
if (!AuthUtil.isNoLoginResources(request)) {
//获取token
String token = request.getHeader(TOKEN);
//token为空不执行下面代码 放行
if (StringUtils.isNotEmpty(token)) {
//解析token
Claims claims = JwtUtil.parseJWT(token);
if(ObjectUtil.isEmpty(claims)){
ResponseUtil.error(HttpStatus.UNAUTHORIZED,ResultEnum.TOKEN_ERROR);
return;
}
String userId = claims.getSubject();
//从redis中获取token 获取到登陆用户信息
LoginUser loginUser = redisCache.getCacheObject(TOKEN + userId);
if (ObjectUtil.isEmpty(loginUser)) {
ResponseUtil.error(HttpStatus.UNAUTHORIZED,ResultEnum.TOKEN_ERROR);
return;
}
//获取到登陆用户信息 交给 Authentication 设置上下文 SecurityContextHolder
UsernamePasswordAuthenticationToken authenticationToken
= new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
/*LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{
tokenService.verifyToken(loginUser);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}*/
//放行
chain.doFilter(request, response);
}
}