In my project, I added spring security using jwt. If token is missing or invalid, it will response with 401 and if permission is not set right, it will response with 403. I was wondering how I can customize the body of these two responses. I am creating response with custom messages using @ControllerAdvice like this:
@ControllerAdvice
public class HealthDataProviderRestExceptionHandler {
    private static final Logger LOG = LoggerFactory.getLogger(HealthDataProviderRestExceptionHandler.class);
    private static final String INVALID_REQUEST_MSG = "Invalid Request.";
    private static final String PROCESSING_ERROR_MSG = "Error while processing request.";
    /**
     * Customizes response for {@link HttpMessageNotReadableException}.
     *
     * @param ex the httpMessageNotReadableException
     * @return HttpStatus.BAD_REQUEST
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity<Object> handleIncorrectJsonException(HttpMessageNotReadableException ex) {
        LOG.error(INVALID_REQUEST_MSG, ex);
        return new ResponseEntity<>(getErrorMessage(INVALID_REQUEST_MSG, OperationOutcome.IssueType.INVALID),
                setHeaders(), HttpStatus.BAD_REQUEST);
    }
    /**
     * Customizes response for {@link MethodArgumentNotValidException}.
     *
     * @param ex the methodArgumentNotValidException
     * @return HttpStatus.BAD_REQUEST
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        LOG.error(INVALID_REQUEST_MSG, ex);
        return new ResponseEntity<>(getErrorMessage(INVALID_REQUEST_MSG, OperationOutcome.IssueType.INVALID),
                setHeaders(), HttpStatus.BAD_REQUEST);
    }
    /**
     * Customized response for {@link HealthDataProviderServiceException}.
     *
     * @param ex the HealthDataProviderServiceException
     * @return HttpStatus.INTERNAL_SERVER_ERROR
     */
    @ExceptionHandler(HealthDataProviderServiceException.class)
    public ResponseEntity<Object> handleHealthDataProviderServiceException(
            final HealthDataProviderServiceException ex) {
        LOG.error(PROCESSING_ERROR_MSG, ex);
        return new ResponseEntity<>(getErrorMessage(PROCESSING_ERROR_MSG, OperationOutcome.IssueType.EXCEPTION),
                setHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
    /**
     * Customized response for {@link HealthDataProxyException}.
     *
     * @param ex HealthDataProxyException
     * @return http status returned from proxy
     */
    @ExceptionHandler(HealthDataProxyException.class)
    public ResponseEntity<Object> handleHealthDataProxyException(final HealthDataProxyException ex) {
        LOG.error(PROCESSING_ERROR_MSG, ex);
        return new ResponseEntity<>(ex.getHealthDataProxyResponse(), setHeaders(), ex.getStatus());
    }
    /**
     * Customizes response for {@link MethodArgumentTypeMismatchException }.
     *
     * @return HttpStatus.BAD_REQUEST
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public ResponseEntity<Object> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex) {
        LOG.error(INVALID_REQUEST_MSG, ex);
        return new ResponseEntity<>(getErrorMessage(INVALID_REQUEST_MSG, OperationOutcome.IssueType.INVALID),
                setHeaders(), HttpStatus.BAD_REQUEST);
    }
    /**
     * Customizes response for {@link ConstraintViolationException }.
     *
     * @return HttpStatus.BAD_REQUEST
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Object> handleConstraintViolationException(ConstraintViolationException ex) {
        LOG.error(INVALID_REQUEST_MSG, ex);
        return new ResponseEntity<>(getErrorMessage(INVALID_REQUEST_MSG, OperationOutcome.IssueType.INVALID),
                setHeaders(), HttpStatus.BAD_REQUEST);
    }
    /**
     * Customizes response for {@link Exception}.
     *
     * @param ex the exception
     * @return HttpStatus.INTERNAL_SERVER_ERROR
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> handleException(Exception ex) {
        LOG.error(PROCESSING_ERROR_MSG, ex);
        return new ResponseEntity<>(getErrorMessage(PROCESSING_ERROR_MSG, OperationOutcome.IssueType.EXCEPTION),
                setHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
    private MultiValueMap<String, String> setHeaders() {
        MultiValueMap<String, String> headers = new HttpHeaders();
        headers.set(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        headers.set(ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        return headers;
    }
    private String getErrorMessage(String message, OperationOutcome.IssueType issueType) {
        OperationOutcome operationOutcome = new OperationOutcome();
        OperationOutcome.OperationOutcomeIssueComponent component =
                new OperationOutcome.OperationOutcomeIssueComponent();
        component.setSeverity(OperationOutcome.IssueSeverity.ERROR);
        component.setCode(issueType);
        component.setDiagnostics(message);
        operationOutcome.setId(String.valueOf(UUID.randomUUID()));
        operationOutcome.addIssue(component);
        return FhirContext.forR4().newJsonParser().encodeResourceToString(operationOutcome);
    }
}
Based on different exception type, I am generating status and messages. But I am not sure what kind of exception it is throwing for 401 and 403. I am guessing some type of NotAuthorizedException but not 100% sure.. How can I handle them with custom messages?
 
    