Java 如何使用spring security在spring引导应用程序中集中异常处理?
我正在spring boot应用程序中设置jwt身份验证,我希望在一个地方处理所有异常 我知道控制器的异常可以在Java 如何使用spring security在spring引导应用程序中集中异常处理?,java,spring,exception,spring-security,Java,Spring,Exception,Spring Security,我正在spring boot应用程序中设置jwt身份验证,我希望在一个地方处理所有异常 我知道控制器的异常可以在@ControllerAdvice中处理, 对于FilterSecurityInterceptor我可以设置AuthenticationEntryPoint和AccessDeniedManager,对于AuthenticationFilters我可以设置未成功的身份验证管理器。但这似乎太多了,无法处理异常 所以我想让它更集中 我决定简单地重新显示所有异常,以便Tomcat将请求重定向到
@ControllerAdvice
中处理,
对于FilterSecurityInterceptor
我可以设置AuthenticationEntryPoint
和AccessDeniedManager
,对于AuthenticationFilters
我可以设置未成功的身份验证
管理器。但这似乎太多了,无法处理异常
所以我想让它更集中
我决定简单地重新显示所有异常,以便Tomcat
将请求重定向到“/error”
,并将异常详细信息设置为请求属性<代码>“/error”由控制器处理,控制器从请求中提取异常并重新发送,因此异常直接进入异常处理程序
在我的身份验证过滤器(我有两个)中,我在构造函数中执行此操作:this.setAuthenticationFailureHandler(
ExceptionHandlerUtils::authenticationFailureHandler)代码>
对于FilterSecurityInterceptor(在安全配置中)也是如此:
然后,由于未处理的异常(filterChain
不处理异常(除了一些AuthenticationException
等),请求处理回滚到最终捕获它的org.apache.catalina.core.StandardWrapperValve
,执行以下操作:
try {
*shortly, filterChain.doFilter(...)*
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
container.getLogger().error(sm.getString(
"standardWrapper.serviceException", wrapper.getName(),
context.getName()), e);
throwable = e;
exception(request, response, e);
}
这里发生了不需要的日志记录,并且exception(…)
方法将exception设置为请求属性,然后org.apache.catalina.core.StandardHostValve#throwable(…)
设置一些其他请求属性并将请求重定向到“/error”。然后请求再次通过链到达我的RethrowingErrorController
@RequestMapping("/error")
public Object getError(HttpServletRequest request) throws Throwable {
Object val = request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
if (val != null) {
throw (Throwable) val;
}
/* this should never be called, but whatever */
return "why are you here???";
}
最后由
@ControllerAdvice
@Log4j2
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({RuntimeException.class})
protected ResponseEntity<Object> handleUnexpectedException(
RuntimeException ex, WebRequest request) {
log.error("unexpected conflict:", ex);
Map<?, ?> body = ExceptionHandlerUtils.getErrorAttributes(request, false);
return handleExceptionInternal(ex, body, new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}
但我担心,我可能会错过一些重要的东西。因此,我需要一个更好的解决方案来集中异常,或者一个可靠的方法来隐藏不需要的错误日志
欢迎大家提出改进我的问题的建议
@RequestMapping("/error")
public Object getError(HttpServletRequest request) throws Throwable {
Object val = request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
if (val != null) {
throw (Throwable) val;
}
/* this should never be called, but whatever */
return "why are you here???";
}
@ControllerAdvice
@Log4j2
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({RuntimeException.class})
protected ResponseEntity<Object> handleUnexpectedException(
RuntimeException ex, WebRequest request) {
log.error("unexpected conflict:", ex);
Map<?, ?> body = ExceptionHandlerUtils.getErrorAttributes(request, false);
return handleExceptionInternal(ex, body, new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}
logging:
level:
org.apache.catalina.core: off