Spring AuthenticationEntryPoint returns Tomcat HTML error instead of JSON

Viewed 3505

I am using Spring to expose and API in a larger application. When accessing endpoints that are behind an authenticated() configuration, my application throws an ugly Tomcat HTML error because of the following code:

@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");
    }
}

However, since this is an API I only want to return JSON, like in the rest of my API. For normal exception handling I set up the following @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);
    }
}

Where ErrorResponse is my own little response wrapper, holding the HttpStatus code and exception message. This gets formatted into JSON fine:

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

How can I make sure my AuthenticationEntryPoint which only has a request and response object to return a similar formatted error, instead of the ugly Tomcat HTML page.

1 Answers
Related