【问题标题】:Spring AuthenticationEntryPoint returns Tomcat HTML error instead of JSONSpring AuthenticationEntryPoint 返回 Tomcat HTML 错误而不是 JSON
【发布时间】:2018-03-03 02:25:15
【问题描述】:

我正在使用 Spring 在更大的应用程序中公开 API。当访问位于 authenticated() 配置后面的端点时,我的应用程序会因为以下代码而抛出一个丑陋的 Tomcat HTML 错误:

@Component
public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
    }
}

但是,由于这是一个 API,我只想返回 JSON,就像我的 API 的其余部分一样。对于正常的异常处理,我设置了以下@ControllerAdvice

@ControllerAdvice
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {

    /**
     * Default internal BadCredentialsException handler. Respond with 401 Unauthorized
     */
    @ExceptionHandler(value = BadCredentialsException.class)
    public ResponseEntity<Object> handleBadCredentialsException(BadCredentialsException e, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return handleExceptionInternal(e, null, headers, HttpStatus.UNAUTHORIZED, request);
    }

    /**
     * Fallback default exception handler. Respond with 500
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<Object> handleFallbackException(Exception e, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return handleExceptionInternal(e, null, headers, HttpStatus.INTERNAL_SERVER_ERROR, request);
    }

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body,
            HttpHeaders headers, HttpStatus status, WebRequest request) {

        final ErrorResponse error = new ErrorResponse(status, ex.getMessage());

        if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
            request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
        }

        return new ResponseEntity<Object>(error, headers, status);
    }
}

ErrorResponse 是我自己的小响应包装器,其中包含 HttpStatus 代码和异常消息。这被格式化为 JSON 格式:

{
    "status": 401,
    "message": "Bad credentials"
}

我如何确保我的AuthenticationEntryPoint 只有一个请求和响应对象才能返回类似格式的错误,而不是丑陋的 Tomcat HTML 页面。

【问题讨论】:

标签: java spring spring-security


【解决方案1】:

您可以根据需要更改HttpServletResponse。 看一看:https://stackoverflow.com/a/19788700/1490806

【讨论】:

  • 手动编写 JSON 字符串或使用 ObjectMapper 感觉非常丑陋和 hacky。真的没有合适的方法来做到这一点吗?感觉就像我错误地使用了 Spring。如果您需要在此 AuthenticationEntryPoint 中再次执行此操作,那么在 1 个位置定义您的异常处理有什么意义?
  • spring 安全过滤器发生在 spring dispatcher servlet 之前。所以我猜春天无法控制安全过滤器链上发生的异常。 visola.github.io/img/blog/spring-security-architecture.png我不知道有其他方法可以做到这一点。
猜你喜欢
  • 2018-10-29
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多