Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用spring security在spring引导应用程序中集中异常处理?_Java_Spring_Exception_Spring Security - Fatal编程技术网

Java 如何使用spring security在spring引导应用程序中集中异常处理?

Java 如何使用spring security在spring引导应用程序中集中异常处理?,java,spring,exception,spring-security,Java,Spring,Exception,Spring Security,我正在spring boot应用程序中设置jwt身份验证,我希望在一个地方处理所有异常 我知道控制器的异常可以在@ControllerAdvice中处理, 对于FilterSecurityInterceptor我可以设置AuthenticationEntryPoint和AccessDeniedManager,对于AuthenticationFilters我可以设置未成功的身份验证管理器。但这似乎太多了,无法处理异常 所以我想让它更集中 我决定简单地重新显示所有异常,以便Tomcat将请求重定向到

我正在spring boot应用程序中设置jwt身份验证,我希望在一个地方处理所有异常

我知道控制器的异常可以在
@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