Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.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 使用@ControllerAdvice注释@ExceptionHandler(Exception.class)正在工作,但@ExceptionHandler({AuthenticationException.class)不工作_Java_Spring Boot_Spring Mvc_Spring Security - Fatal编程技术网

Java 使用@ControllerAdvice注释@ExceptionHandler(Exception.class)正在工作,但@ExceptionHandler({AuthenticationException.class)不工作

Java 使用@ControllerAdvice注释@ExceptionHandler(Exception.class)正在工作,但@ExceptionHandler({AuthenticationException.class)不工作,java,spring-boot,spring-mvc,spring-security,Java,Spring Boot,Spring Mvc,Spring Security,我正在尝试使用@ControllerAdvice注释在spring boot中返回自定义JSON响应。下面是我的代码。defaultExceptionHandler在应用程序中出错或spring boot服务引发异常时会被调用。但是handleAuthenticationException即使输入,也不会被调用错误的凭据。在这种情况下,将返回默认的spring启动响应。此服务是安全的,并且已设置为使用基本身份验证 @Order(Ordered.HIGHEST_PRECEDENCE) @Contr

我正在尝试使用
@ControllerAdvice
注释在spring boot中返回自定义JSON响应。下面是我的代码。
defaultExceptionHandler
在应用程序中出错或spring boot服务引发异常时会被调用。但是
handleAuthenticationException
即使输入,也不会被调用错误的凭据。在这种情况下,将返回默认的spring启动响应。此服务是安全的,并且已设置为使用基本身份验证

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    @ExceptionHandler({AuthenticationException.class})
    public ServiceError handleAuthenticationException(final Exception ex) {
        //LOGGER.error(ex.toString(), ex);
        return new ServiceError(ServiceErrorCode.REQUEST_INVALID, ex.getMessage());
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ServiceError defaultExceptionHandler(final Exception ex) {
        //LOGGER.error(ex.toString(), ex);
        return new ServiceError(ServiceErrorCode.SERVICE_ERROR, ex.getMessage());
    }
}
获取返回而不是自定义响应的默认响应:

   {
"timestamp": 16654436345,
"status": 401,
"error": "Unauthorized",
"message": "Bad credentials",
"path": "/mycontroller"}
安全配置类:

    @Configuration
public static class ServiceWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.
            csrf().
            disable().
            exceptionHandling().
        and().
            headers().
            frameOptions().
            disable().
        and().
            sessionManagement().
            sessionCreationPolicy(SessionCreationPolicy.STATELESS).
        and().
            authorizeRequests().
            antMatchers("/service/**").authenticated().
            antMatchers("/health").permitAll().
            antMatchers("/metrics").permitAll().
            antMatchers("/info").hasAuthority(AuthoritiesConstants.ADMIN).
            anyRequest().authenticated().and().httpBasic();
    }
}

SpringMVC基于servlet,SpringSecurity基于过滤器,过滤器在servlet之前,因此控制器中的异常处理程序将不会执行,因为它在过滤器中已经失败

如果要处理
AuthenticationException
,则需要处理它以实现
AuthenticationEntryPoint
并重写
开始
方法

public void commence(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException authException) throws IOException, ServletException
http.exceptionHandling().authenticationEntryPoint(myEntryPoint());


AuthenticationException
AccessDeniedException
已由
ExceptionTranslationFilter
处理。只需注入
AuthenticationEntryPoint
AccessDeniedHandler
(处理
AccessDeniedException

根据您设置安全配置的方式(您没有显示),401可能在MVC调度发生之前被触发。打开日志记录到
DEBUG
并发布结果。感谢chrylis的建议。发布安全配置安全代码似乎正在发回
HttpServletResponse.SC\u响应-给定401。因此,预期的异常从未被抛出。奇怪的是,在我的例子中,异常在servlet之前的过滤器中,为什么这不起作用