My handleSecurityExceptions() method always returns a HTTP error status of 500 to the client when not requesting JSON (such as when requesting HTML). I am making a wild guess this is because I'm doing something wrong and causing another internal exception that's being swallowed but could be way off base. Uncommenting the commented out lines in ApplicationResponseEntityExceptionHandler provides a work-around to get rid of the issue but what's the right way of doing what I'm doing below? Presumably there's a proper way to get spring to format MessageResponse?
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class ApplicationResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
static final Logger logger = LoggerFactory.getLogger(ApplicationResponseEntityExceptionHandler.class);
private Boolean canAcceptJson(WebRequest request) {
boolean canAccept = false;
String[] accepts = request.getHeaderValues("accept");
for (String value : (accepts == null ? new String[]{} : accepts)) {
for (String directive : value.toLowerCase().split(",")) {
directive=directive.trim();
canAccept = directive.toLowerCase().startsWith("application/json") && (directive.length() == 16 || directive.charAt(16) == ',' || directive.charAt(16) == ';');
if (canAccept)
break;
}
}
return canAccept;
}
@ExceptionHandler(value
= {ApplicationSecurityException.class})
protected ResponseEntity<Object> handleSecurityExceptions(
ApplicationSecurityException ex, WebRequest request) {
logger.info("Security exception {}", ex.getMessage());
// if (canAcceptJson(request))
return handleExceptionInternal(ex, new MessageResponse(ex.getMessage()),
new HttpHeaders(), HttpStatus.UNAUTHORIZED, request);
// else
// return handleExceptionInternal(ex, ex.getMessage(),
// new HttpHeaders(), HttpStatus.UNAUTHORIZED, request);
}
}
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@AllArgsConstructor
public class MessageResponse {
@Getter
@Setter
private String message;
public String toString() {
return message;
}
}
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class ApplicationSecurityException extends RuntimeException {
@Getter
final String message;
}