binarylegit
binarylegit

Reputation: 379

In Spring Security how do I capture exceptions from a custom AuthenticationManager?

I'm using Crowd's Java integration into Spring Security which involves configuring Crowds SimpleAuthenticationManager as an authentication provider. The SimpleAuthenticationManager throws several exceptions when a user fails to be authenticated based on why they could not be authenticated. I was wondering within Spring Security how I can capture that exception and return a JSON response to the client?

I've tried adding an AccessDeniedHandler however this receives a new exception which does not have the original exception as a cause.

Upvotes: 0

Views: 964

Answers (2)

binarylegit
binarylegit

Reputation: 379

I missed this post when googling and searching StackOverflow: Spring security 3 http-basic authentication-success-handler

Turns out, as this other question/answer points out, you need to extend BasicAuthenticationFilter and implement the onUnsuccessfulAuthentication() method. Then add it to your security configuration with:

http.addFilter(new CustomBasicAuthenticationFilter(authenticationManagerBean()))

EDIT Actually it appears that Spring is still wrapping the exceptions at this point, however you are able to get some slightly more specific exceptions, which is helpful.

Upvotes: 0

Glim
Glim

Reputation: 361

You can extends ResponseEntityExceptionHandler with the @ControllerAdvice annotation. This will capture exception and you can handle and send a custom response. Example:

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

}

Upvotes: -1

Related Questions