В Spring Security как мне перехватить исключения из пользовательского AuthenticationManager?
Я использую интеграцию Java Crowd с Spring Security, которая включает в себя настройку Crowds SimpleAuthenticationManager в качестве поставщика аутентификации. SimpleAuthenticationManager генерирует несколько исключений, когда пользователь не может пройти аутентификацию, основываясь на том, почему он не может быть аутентифицирован. Мне было интересно в Spring Security, как я могу перехватить это исключение и вернуть JSON-ответ клиенту?
Я попытался добавить AccessDeniedHandler, однако он получает новое исключение, которое не имеет исходного исключения в качестве причины.
2 ответа
Я пропустил этот пост при поиске в Google и поиске Stackru: Spring security 3 http-basic аутентификация-обработчик успеха
Оказывается, как указывает этот другой вопрос / ответ, вам необходимо расширить BasicAuthenticationFilter и реализовать метод onUnsuccessfulAuthentication(). Затем добавьте его в конфигурацию безопасности с помощью:
http.addFilter(new CustomBasicAuthenticationFilter(authenticationManagerBean()))
РЕДАКТИРОВАТЬ На самом деле кажется, что Spring все еще оборачивает исключения на этом этапе, однако вы можете получить некоторые более конкретные исключения, что полезно.
Вы можете продлить ResponseEntityExceptionHandler
с @ControllerAdvice
аннотаций. Это захватит исключение, и вы можете обработать и отправить пользовательский ответ. Пример:
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(CustomExceptionHandler.class);
public CustomExceptionHandler() {
}
// overriding an exception that already is been handled in ResponseEntityExceptionHandler
@Override
protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
log.warn(ex.toString());
final String parameter = ex.getParameter().getParameterName();
final String detailMessage = ex.getMessage();
final String message = "Parameter " + parameter + " is missing.";
final ErrorMessageDTO result = new ErrorMessageDTO(HttpStatus.BAD_REQUEST, message, parameter, detailMessage, null);
return ResponseEntity.badRequest().body(result);
}
// Custom handle to intercept BadCredentialsException
@ExceptionHandler(BadCredentialsException.class)
@ResponseBody
ResponseEntity<Object> handleBadCredentialsException(HttpServletRequest req,
BadCredentialsException ex) {
log.warn(ex.toString());
final ErrorMessageDTO result = new ErrorMessageDTO(HttpStatus.UNAUTHORIZED, ex.getMessage());
return ResponseEntity.badRequest().body(result);
}
}