Spring AuthenticationEntryPoint 返回 Tomcat HTML 错误而不是 JSON

Chr*_*ker 5 java spring spring-security

我正在使用 Spring 在更大的应用程序中公开 API。当访问authentiated()配置后面的端点时,我的应用程序由于以下代码而抛出一个丑陋的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");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,由于这是一个 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我自己的小响应包装器在哪里ErrorResponse,保存 HttpStatus 代码和异常消息。这可以很好地格式化为 JSON:

{
    "status": 401,
    "message": "Bad credentials"
}
Run Code Online (Sandbox Code Playgroud)

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

ilo*_*una 0

HttpServletResponse您可以根据需要更改。看一下:/sf/answers/1385209031/

  • 手动编写 JSON 字符串或使用 ObjectMapper 感觉非常丑陋和 hacky。难道真的没有正确的方法来做到这一点吗?感觉好像我错误地使用了Spring。如果您需要在此 AuthenticationEntryPoint 中再次执行异常处理,那么在 1 处定义异常处理有何意义? (2认同)