1.問(wèn)題
使用SpringSecurity時(shí)候瞧哟,自定義過(guò)濾器不走全局統(tǒng)一異常喷楣,走過(guò)濾器鏈異常處理
2. 全局統(tǒng)一異常
@RestControllerAdvice
@Slf4j
public class MyExceptionHandler {
@ExceptionHandler(CustomException.class)
public R commonException(CustomException e) {
log.debug("自定義異常信息:", e);
return R.error(e.getCode(), e.getMsg());
}
@ExceptionHandler(Exception.class)
public R handlerException(Exception e) {
log.error("系統(tǒng)異常信息:", e);
return R.error(StatusCode.FAIL);
}
}
3.自定義Filter
@WebFilter(urlPatterns = "/index/getSmsCode")
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
...
throw new CustomException()
...
filterChain.doFilter(servletRequest, servletResponse);
}
}
要使上面@WebFilter生效规惰,需要啟動(dòng)類(lèi)添加@ServletComponentScan("路徑"),
注意丹弱,若在上面過(guò)濾器中添加@component氮帐,則urlPatterns不生效,其他url也會(huì)走此過(guò)濾器
4.解決
全局統(tǒng)一異常處理只能處理控制器中發(fā)生的異常扎阶。要在Spring Security過(guò)濾器鏈中重用此功能汹胃,需要定義過(guò)濾器并將其掛鉤到安全配置中。過(guò)濾器需要將異常重定向到統(tǒng)一異常處理中乘陪。
①.針對(duì)自定義统台,特定過(guò)濾器異常走全局異常
@WebFilter(urlPatterns = "/index/getSmsCode")
@Slf4j
public class SmsFilter implements Filter {
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
...
throw new CustomException(StatusCode.ERROR_PARAMETER);
...
filterChain.doFilter(servletRequest, servletResponse);
} catch (Exception e) {
resolver.resolveException((HttpServletRequest)request, (HttpServletResponse) servletResponse, null, e);
}
}
}
②.配置一處雕擂,是其他過(guò)濾器走全局也生效
自定義過(guò)濾器
@Component
public class FilterChainExceptionHandler extends OncePerRequestFilter {
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (Exception e) {
log.error("Spring Security Filter Chain Exception:", e);
resolver.resolveException(request, response, null, e);
}
}
}
然后啡邑,將創(chuàng)建的過(guò)濾器添加到SecurityConfiguration。您需要非常早地將其掛接到鏈中井赌,因?yàn)椴粫?huì)捕獲次過(guò)濾器之前過(guò)濾的異常谤逼。比如在LogoutFilter之前過(guò)濾,退出異常走全局
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private FilterChainExceptionHandler filterChainExceptionHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(filterChainExceptionHandler, LogoutFilter.class)
(...)
}
}
參考: https://stackoverflow.com/questions/34595605/how-to-manage-exceptions-thrown-in-filters-in-spring